package com.cloudkinto.service.order.outbound.impl;

import cn.afterturn.easypoi.csv.entity.CsvExportParams;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cloudkinto.bo.order.outbound.NormalOrderOutboundQueryBo;
import com.cloudkinto.common.BeanConvert;
import com.cloudkinto.common.ExcelExportTitleStyle;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.utils.CsvUtils;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.dao.LocationCategoryDao;
import com.cloudkinto.dao.OrderOutboundDao;
import com.cloudkinto.dto.order.common.ExportZipDto;
import com.cloudkinto.dto.order.outbound.oldSys.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.enumType.order.outbound.SalesPlatformEnum;
import com.cloudkinto.service.channel.LogisticsChannelService;
import com.cloudkinto.service.order.outbound.OrderOutboundPackageDetailService;
import com.cloudkinto.service.order.outbound.OrderOutboundPackageService;
import com.cloudkinto.service.order.outbound.OrderOutboundProductService;
import com.cloudkinto.service.order.outbound.OutboundOldExportService;
import com.cloudkinto.service.product.ProductCategoryService;
import com.cloudkinto.service.product.ProductService;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.warehouse.WarehouseService;
import com.cloudkinto.utils.BeanCopierUtils;
import com.cloudkinto.vo.order.outbound.NormalOutboundVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author long
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class OutboundOldExportServiceImpl implements OutboundOldExportService {

    private final OrderOutboundDao outboundDao;
    private final WarehouseService warehouseService;
    private final LogisticsChannelService logisticsChannelService;
    private final JpRegionService jpRegionService;
    private final OrderOutboundProductService outboundProductService;
    private final ProductService productService;
    private final ProductCategoryService productCategoryService;
    private final LocationCategoryDao locationCategoryDao;
    private final OrderOutboundPackageService outboundPackageService;
    private final OrderOutboundPackageDetailService outboundPackageDetailService;

    private final String regex = "^\\d{4}/(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])$";
    private final String regex1 = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$";

    @Override
    public void exportOrderFileUseZip(NormalOrderOutboundQueryBo bo, HttpServletResponse response) throws IOException {
        if (Objects.nonNull(bo.getExcludeNotInTrackId()) && bo.getExcludeNotInTrackId()) {
            Long trackIdByExport = bo.getTrackIdByExport();
            if (Objects.nonNull(trackIdByExport)) {
                String channelCode = null;
                if (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_one";
                }
                if (StaticDict.Order_CM_Track.YamatoMore.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_more";
                }
                if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_zhai";
                }
                if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(trackIdByExport)) {
                    channelCode = "sawaga";
                }
                if (StaticDict.Order_CM_Track.KKKK.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_box";
                }
                LogisticsChannelDo channelDo = logisticsChannelService.lambdaQuery()
                        .eq(LogisticsChannelDo::getChannelCode, channelCode)
                        .last("limit 1")
                        .one();
                if (Objects.nonNull(channelDo)) {
                    bo.setLogisticsChannelIdList(Collections.singletonList(channelDo.getId()));
                }
            }
        }
        List<NormalOutboundVo> outboundVoList = outboundDao.getNormalListPage(bo);
        if (CollUtil.isEmpty(outboundVoList)) {
            throw new BizException(SysConstant.No_Data);
        }
        Map<Long, WarehouseDo> whIdMatch = warehouseService.lambdaQuery()
                .in(WarehouseDo::getId, outboundVoList.stream().map(NormalOutboundVo::getWhId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(WarehouseDo::getId, val -> val));
        Map<Long, LogisticsChannelDo> lcIdMatch = logisticsChannelService.lambdaQuery()
                .in(LogisticsChannelDo::getId, outboundVoList.stream().map(NormalOutboundVo::getLogisticsChannelId).collect(Collectors.toList())).list().stream().collect(Collectors.toMap(LogisticsChannelDo::getId, val -> val));
        List<OutboundOldExportDto> dtoList = new ArrayList<>();
        for (NormalOutboundVo outboundVo : outboundVoList) {
            OutboundOldExportDto dto = JSONUtil.toBean(JSONUtil.toJsonStr(outboundVo), OutboundOldExportDto.class);
            WarehouseDo warehouseDo = whIdMatch.get(outboundVo.getWhId());
            if (warehouseDo == null) {
                dto.setStorageId(StaticDict.CM_Storage.MyselfStorage.getValue());
            } else {
                dto.setStorageId(warehouseDo.getWarehouseType().equals(0) ? StaticDict.CM_Storage.MyselfStorage.getValue() : StaticDict.CM_Storage.ThirdStorage.getValue());
            }
            LogisticsChannelDo channelDo = lcIdMatch.get(outboundVo.getLogisticsChannelId());
            if (Objects.nonNull(channelDo)) {
                switch (channelDo.getChannelCode()) {
                    case "yamato_one":
                        dto.setTrackId(StaticDict.Order_CM_Track.YamatoOne.getValue());
                        break;
                    case "yamato_more":
                        dto.setTrackId(StaticDict.Order_CM_Track.YamatoMore.getValue());
                        break;
                    case "yamato_zhai":
                        dto.setTrackId(StaticDict.Order_CM_Track.YamatoZhai.getValue());
                        break;
                    case "sawaga":
                        dto.setTrackId(StaticDict.Order_CM_Track.Sagawa.getValue());
                        break;
                    case "yamato_box":
                        dto.setTrackId(StaticDict.Order_CM_Track.KKKK.getValue());
                        break;
                    default:
                        dto.setTrackId(null);
                }
            } else {
                dto.setTrackId(null);
            }
            dtoList.add(dto);
        }
        String fileNameTime = DateUtil.format(new Date(), "yyyyMMdd-HH時");
        //导出zip的名字根据情况命名
        String fileName;
        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
        zos.setLevel(1);
        //Excel文件导出配置
        ExportParams excelParam = new ExportParams();
        excelParam.setType(ExcelType.XSSF);
        excelParam.setStyle(ExcelExportTitleStyle.class);
        //Csv文件导出配置（去标题）
        CsvExportParams csvParamWithoutHead = new CsvExportParams();
        csvParamWithoutHead.setCreateHeadRows(false);
        csvParamWithoutHead.setEncoding("Shift-JIS");
        csvParamWithoutHead.setTextMark("");
        //Csv文件导出配置
        CsvExportParams csvParam = new CsvExportParams();
        csvParam.setEncoding("Shift-JIS");
        csvParam.setTextMark("");
        //所有输出流及zip文件都放在这个集合里面
        List<ExportZipDto> exportZipDtoList = new ArrayList<>(20);
        //添加未分单的预约单
        List<OutboundOldExportDto> reserveList = dtoList.stream()
                .filter(o -> o.getReserveFlag().equals(1) && Objects.isNull(o.getTrackId()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(reserveList)) {
            List<OrderFileByReserveDto> orderFileByReserveDtos = JSONUtil.toList(JSONUtil.toJsonStr(reserveList), OrderFileByReserveDto.class);
            //根据预约时间段分文件
            orderFileByReserveDtos.stream().map(OrderFileByReserveDto::getReserveBeginTime).distinct().forEach(item -> {
                List<OrderFileByReserveDto> list = orderFileByReserveDtos.stream()
                        .filter(o -> o.getReserveBeginTime().compareTo(item) == 0)
                        .collect(Collectors.toList());
                OrderFileByReserveDto tempDto = list.get(0);
                String timeBand = DateUtil.format(tempDto.getReserveBeginTime(), "MM.dd-") +
                                  DateUtil.format(tempDto.getReserveEndTime(), "MM.dd");
                List<List<OrderFileByReserveDto>> partition = ListUtil.partition(list, 5000);
                for (int i = 0; i < partition.size(); i++) {
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    List<OrderFileByReserveDto> temp = BeanCopierUtils.listCopyMapper(
                            partition.get(i),
                            OrderFileByReserveDto.class,
                            OrderFileByReserveDto.class
                    );
                    CsvUtils.exportCsv(csvParam, OrderFileByReserveDto.class, temp, outputStream);
                    String itemFileNum;
                    long num = partition.get(i).stream().filter(distinctByKey(OrderFileByReserveDto::getOutboundNo)).count();
                    if (partition.size() > 1) {
                        itemFileNum = fileNameTime + "予約" + timeBand + "-" + num + "(" + (i + 1) + ").csv";
                    } else {
                        itemFileNum = fileNameTime + "予約" + timeBand + "-" + num + ".csv";
                    }
                    exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), outputStream));
                }
            });
        }
        //未进行导出操作的数据
        List<OutboundOldExportDto> noOperateList = dtoList.stream()
                .filter(o -> !o.getReserveFlag().equals(1) && Objects.isNull(o.getTrackId()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(noOperateList)) {
            List<OrderFileByNoOperateDto> orderFileByNoOperateDtos = JSONUtil.toList(JSONUtil.toJsonStr(noOperateList), OrderFileByNoOperateDto.class);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            CsvUtils.exportCsv(csvParam, OrderFileByNoOperateDto.class, orderFileByNoOperateDtos, outputStream);
            String itemFile = fileNameTime + "指定されていないチャネル-" + orderFileByNoOperateDtos.size() + ".csv";
            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFile), outputStream));
        }
        fileName = "第三方仓库订单.zip";
        //数据中含有未分单的预约单的订单，需要排除掉
        dtoList = dtoList.stream()
                .filter(o -> Objects.nonNull(o.getTrackId()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(dtoList)) {
            //手动指定为三方仓库,渠道在第三方仓库前置方法内强制修改原有订单数据
            if (StaticDict.CM_Storage.ThirdStorage.getValue().equals(bo.getWhIdByExport())) {
                fileName = "第三方仓库订单.zip";
                //排除佐川
                dtoList = dtoList.stream()
                        .filter(o -> !StaticDict.Order_CM_Track.Sagawa.getValue().equals(o.getTrackId()))
                        .collect(Collectors.toList());
                List<OrderFileByThirdPartyDto> thirdPartyDtoList = BeanCopierUtils.listCopyMapper(
                        dtoList,
                        OutboundOldExportDto.class,
                        OrderFileByThirdPartyDto.class
                );
                //宅急便分普通单0和次日达2
                Map<Integer, List<OrderFileByThirdPartyDto>> typeMap = thirdPartyDtoList.stream()
                        .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                        .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getReserveFlag));
                //投函分一个黑猫投函和投函多件(非宅急便订单)
                Map<Long, List<OrderFileByThirdPartyDto>> trackMap = thirdPartyDtoList.stream()
                        .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                        .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getTrackId));
                if (CollUtil.isNotEmpty(typeMap.get(1))) {
                    typeMap.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMap.get(1));
                    typeMap.remove(1);
                }
                //判断 普通单宅急便 + 单个黑猫投函 在10000行左右进行合并
                if ((CollUtil.isEmpty(typeMap.get(0)) ? 0 : typeMap.get(0).size())
                    + (CollUtil.isEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                        ? 0
                        : trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                    < 10100) {
                    //合并的订单数据
                    //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                    List<OrderFileByThirdPartyDto> combineDailyList = new ArrayList<>(1000);
                    //次日达的一件投函
                    List<OrderFileByThirdPartyDto> yamatoOneNextDayList = new ArrayList<>(1000);
                    if (CollUtil.isNotEmpty(typeMap.get(0))) {
                        //日常单宅急便
                        combineDailyList.addAll(typeMap.get(0));
                        typeMap.remove(0);
                    }
                    if (CollUtil.isNotEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                        //日常单和预约黑猫投函
                        combineDailyList.addAll(
                                trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        //次日达黑猫投函
                        yamatoOneNextDayList.addAll(
                                trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        trackMap.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                    }
                    //前置处理订单数据
                    List<OrderFileByThirdPartyDto> dtos = handlerExportBeforeForThirdParty(combineDailyList, bo.getTrackIdByExport());
                    if (CollUtil.isNotEmpty(dtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dtos,
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dtos.size();
                        itemFileNum = fileNameTime + "三方倉-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                    List<OrderFileByThirdPartyDto> dailyDtos = handlerExportBeforeForThirdParty(yamatoOneNextDayList, bo.getTrackIdByExport());
                    if (CollUtil.isNotEmpty(dailyDtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dailyDtos,
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dailyDtos.size();
                        itemFileNum = fileNameTime + "三方倉-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }
                for (Map.Entry<Integer, List<OrderFileByThirdPartyDto>> entry : typeMap.entrySet()) {
                    Integer reserveFlag = entry.getKey();
                    List<OrderFileByThirdPartyDto> sagawaList = entry.getValue();
                    List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                            handlerExportBeforeForThirdParty(sagawaList, bo.getTrackIdByExport()),
                            10000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }

                for (Map.Entry<Long, List<OrderFileByThirdPartyDto>> entry : trackMap.entrySet()) {
                    Long track = entry.getKey();
                    List<OrderFileByThirdPartyDto> sendLetterList = entry.getValue();
                    List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                            handlerExportBeforeForThirdParty(sendLetterList, bo.getTrackIdByExport()),
                            10000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }

                //=====================三方仓B2模板================
                //宅急便分普通单0和次日达2
                Map<Integer, List<OutboundOldExportDto>> typeMapB2 = dtoList.stream()
                        .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                        .collect(Collectors.groupingBy(OutboundOldExportDto::getReserveFlag));
                //投函分一个黑猫投函和投函多件(非宅急便订单)
                Map<Long, List<OutboundOldExportDto>> trackMapB2 = dtoList.stream()
                        .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                        .collect(Collectors.groupingBy(OutboundOldExportDto::getTrackId));
                if (CollUtil.isNotEmpty(typeMapB2.get(1))) {
                    typeMapB2.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMapB2.get(1));
                    typeMapB2.remove(1);
                }
                //判断 普通单宅急便 + 单个黑猫投函 在1000行左右进行合并
                if ((CollUtil.isEmpty(typeMapB2.get(0)) ? 0 : typeMapB2.get(0).size())
                    + (CollUtil.isEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                        ? 0
                        : trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                    < 1100) {
                    //合并的订单数据
                    //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                    List<OutboundOldExportDto> combineDailyList = new ArrayList<>(1000);
                    //次日达的一件投函
                    List<OutboundOldExportDto> yamatoOneNextDayList = new ArrayList<>(1000);
                    if (CollUtil.isNotEmpty(typeMapB2.get(0))) {
                        //日常单宅急便
                        combineDailyList.addAll(typeMapB2.get(0));
                        typeMapB2.remove(0);
                    }
                    if (CollUtil.isNotEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                        //日常单和预约黑猫投函
                        combineDailyList.addAll(
                                trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        //次日达黑猫投函
                        yamatoOneNextDayList.addAll(
                                trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        trackMapB2.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                    }
                    //前置处理订单数据
                    List<OrderFileByBlackCatDto> dtos = this.handlerExportBeforeForBlackCatB2(
                            combineDailyList,
                            bo.getTrackIdByExport(),
                            OrderFileByBlackCatDto::getProductCode1
                    );
                    if (CollUtil.isNotEmpty(dtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dtos,
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dtos.size();
                        itemFileNum = fileNameTime + "三方倉B2模板-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                    List<OrderFileByBlackCatDto> dailyDtos = this.handlerExportBeforeForBlackCatB2(
                            yamatoOneNextDayList,
                            bo.getTrackIdByExport(),
                            OrderFileByBlackCatDto::getProductCode1
                    );
                    if (CollUtil.isNotEmpty(dailyDtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dailyDtos,
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dailyDtos.size();
                        itemFileNum = fileNameTime + "三方倉B2模板-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }
                for (Map.Entry<Integer, List<OutboundOldExportDto>> entry : typeMapB2.entrySet()) {
                    Integer reserveFlag = entry.getKey();
                    List<OutboundOldExportDto> sagawaList = entry.getValue();
                    List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatB2(
                                    sagawaList,
                                    bo.getTrackIdByExport(),
                                    OrderFileByBlackCatDto::getProductCode1
                            ),
                            1000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }

                for (Map.Entry<Long, List<OutboundOldExportDto>> entry : trackMapB2.entrySet()) {
                    Long track = entry.getKey();
                    List<OutboundOldExportDto> sendLetterList = entry.getValue();
                    List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatB2(sendLetterList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }
                //=====================三方仓B2模板================

                //-------------api模板数据导出start-------------
                //封装api连接模板数据(排除预约单和次日达的宅急便订单)
                List<OrderFileByApiDto> orderFileByApiDtos = BeanCopierUtils.listCopyMapper(
                        thirdPartyDtoList.stream()
                                .filter(o -> !(o.getTrackId().equals(StaticDict.Order_CM_Track.YamatoZhai.getValue()) && !o.getReserveFlag().equals(0)))
                                .collect(Collectors.toList()),
                        OrderFileByThirdPartyDto.class,
                        OrderFileByApiDto.class
                );
                //指定渠道，只有一个api数据文件
                if (Objects.nonNull(bo.getTrackIdByExport())) {
                    List<List<OrderFileByApiDto>> partition = ListUtil.partition(handlerExportBeforeForApi(orderFileByApiDtos, bo.getTrackIdByExport()), 5000);
                    if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(bo.getTrackIdByExport())) {
                        //宅急便
                        for (int i = 0; i < partition.size(); i++) {
                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                    partition.get(i),
                                    OrderFileByApiDto.class,
                                    OrderFileByApiDto.class
                            );
                            CsvUtils.exportCsv(
                                    csvParam,
                                    OrderFileByApiDto.class,
                                    temp,
                                    outputStream
                            );
                            String itemFileName;
                            long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                            int size = partition.get(i).size();
                            if (partition.size() > 1) {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                            } else {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行.csv";
                            }
                            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                        }
                    } else if (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(bo.getTrackIdByExport())) {
                        //三方仓-黑猫投函api(不包括投函多件)
                        for (int i = 0; i < partition.size(); i++) {
                            ByteArrayOutputStream apiBos = new ByteArrayOutputStream();
                            List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                    partition.get(i),
                                    OrderFileByApiDto.class,
                                    OrderFileByApiDto.class
                            );
                            CsvUtils.exportCsv(
                                    csvParam,
                                    OrderFileByApiDto.class,
                                    temp,
                                    apiBos
                            );
                            String itemFileName;
                            long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                            int size = partition.get(i).size();
                            if (partition.size() > 1) {
                                itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                            } else {
                                itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行.csv";
                            }
                            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), apiBos));
                        }
                    }
                } else {
                    //按照默认渠道分api数据
                    List<OrderFileByApiDto> apiBy300 = orderFileByApiDtos.stream()
                            .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderFileByApiDto.getTrackId()))
                            .collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(apiBy300)) {
                        List<List<OrderFileByApiDto>> partition = ListUtil.partition(handlerExportBeforeForApi(apiBy300, null), 5000);
                        for (int i = 0; i < partition.size(); i++) {
                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                    partition.get(i),
                                    OrderFileByApiDto.class,
                                    OrderFileByApiDto.class
                            );
                            CsvUtils.exportCsv(
                                    csvParam,
                                    OrderFileByApiDto.class,
                                    temp,
                                    outputStream
                            );
                            String itemFileName;
                            long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                            int size = partition.get(i).size();
                            if (partition.size() > 1) {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                            } else {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行.csv";
                            }
                            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                        }
                    }
                    if (apiBy300.size() < orderFileByApiDtos.size()) {
                        List<OrderFileByApiDto> apiBySendLetters = orderFileByApiDtos.stream()
                                .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderFileByApiDto.getTrackId()))
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(apiBySendLetters)) {
                            List<List<OrderFileByApiDto>> partition = ListUtil.partition(handlerExportBeforeForApi(apiBySendLetters, null), 5000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream apiBos = new ByteArrayOutputStream();
                                List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByApiDto.class,
                                        OrderFileByApiDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByApiDto.class,
                                        temp,
                                        apiBos
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), apiBos));
                            }
                        }
                    }
                }
                //-------------api模板数据导出end---------------
            } else if (StaticDict.CM_Storage.MyselfStorage.getValue().equals(bo.getWhIdByExport())
                       && Objects.isNull(bo.getTrackIdByExport())) {
                //本地仓没有指定渠道，按照原订单渠道导出
                fileName = "本地仓库订单.zip";
                Map<Long, List<OutboundOldExportDto>> map = new HashMap<>(8);
                List<OutboundOldExportDto> temp1 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                (Objects.nonNull(orderCrossMallDo.getStorageId())
                                 && StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                ) || (Objects.nonNull(orderCrossMallDo.getTrackId())
                                      && (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderCrossMallDo.getTrackId())
                                          || StaticDict.Order_CM_Track.YamatoMore.getValue().equals(orderCrossMallDo.getTrackId())
                                      ))
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp1)) {
                    map.put(StaticDict.CM_Storage.ThirdStorage.getValue(), temp1);
                }
                List<OutboundOldExportDto> temp2 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                Objects.nonNull(orderCrossMallDo.getStorageId())
                                && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                && Objects.nonNull(orderCrossMallDo.getTrackId())
                                && StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderCrossMallDo.getTrackId())
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp2)) {
                    map.put(StaticDict.Order_CM_Track.YamatoZhai.getValue(), temp2);
                }
                List<OutboundOldExportDto> temp3 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                Objects.nonNull(orderCrossMallDo.getStorageId())
                                && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                && Objects.nonNull(orderCrossMallDo.getTrackId())
                                && StaticDict.Order_CM_Track.Sagawa.getValue().equals(orderCrossMallDo.getTrackId())
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp3)) {
                    map.put(StaticDict.Order_CM_Track.Sagawa.getValue(), temp3);
                }
                List<OutboundOldExportDto> temp4 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                Objects.nonNull(orderCrossMallDo.getStorageId())
                                && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                && Objects.nonNull(orderCrossMallDo.getTrackId())
                                && StaticDict.Order_CM_Track.KKKK.getValue().equals(orderCrossMallDo.getTrackId())
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp4)) {
                    map.put(StaticDict.Order_CM_Track.KKKK.getValue(), temp4);
                }
                map.forEach((trackId, value) -> {
                    try {
                        if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(trackId)) {
                            //黑猫宅急便每1000条数据一个文件
                            List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                    handlerExportBeforeForBlackCat(value, OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
//                        partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                ExcelUtils.exportExcel(
                                        temp,
                                        OrderFileByBlackCatDto.class,
                                        excelParam,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "本地仓-宅急便订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                } else {
                                    itemFileName = fileNameTime + "本地仓-宅急便订单-" + num1 + "件-" + size + "行.xlsx";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        } else if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(trackId)) {
                            //佐川急便
                            ByteArrayOutputStream bos = new ByteArrayOutputStream();
                            ExcelUtils.exportExcel(
                                    this.handlerExportBeforeForSagawa(value, OrderFileBySagawaDto::getProductCode1),
                                    OrderFileBySagawaDto.class,
                                    excelParam,
                                    bos
                            );
                            long num1 = value.stream().filter(distinctByKey(OutboundOldExportDto::getOutboundNo)).count();
                            int size = value.size();
                            exportZipDtoList.add(
                                    new ExportZipDto(
                                            new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.xlsx"),
                                            bos
                                    )
                            );
                            ByteArrayOutputStream csvBos = new ByteArrayOutputStream();
                            CsvUtils.exportCsv(
                                    csvParamWithoutHead,
                                    OrderFileBySagawaDto.class,
                                    handlerExportBeforeForSagawa(value, OrderFileBySagawaDto::getProductCode1),
                                    csvBos
                            );
                            exportZipDtoList.add(
                                    new ExportZipDto(
                                            new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.csv"),
                                            csvBos
                                    )
                            );
                        } else if (StaticDict.Order_CM_Track.KKKK.getValue().equals(trackId)) {
                            //コンパクト
                            List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                    handlerExportBeforeForBlackCat(value, OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
//                        partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                ExcelUtils.exportExcel(
                                        temp,
                                        OrderFileByBlackCatDto.class,
                                        excelParam,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                } else {
                                    itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行.xlsx";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        } else {
                            //投函
                            List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                    handlerExportBeforeForBlackCat(value, OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
//                        partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                ExcelUtils.exportExcel(
                                        temp,
                                        OrderFileByBlackCatDto.class,
                                        excelParam,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "本地仓-黑猫投函订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                } else {
                                    itemFileName = fileNameTime + "本地仓-黑猫投函订单-" + num1 + "件-" + size + "行.xlsx";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            } else if (Objects.nonNull(bo.getTrackIdByExport())) {
                //本地仓库且指定渠道
                fileName = "本地仓订单.zip";
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                //手动指定渠道，按照指定渠道导出，不管原订单渠道
                if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(bo.getTrackIdByExport())) {
                    //黑猫宅急便每1000条数据一个文件
                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                            handlerExportBeforeForBlackCat(dtoList, OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
//                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < partition.size(); i++) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                partition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        ExcelUtils.exportExcel(
                                temp,
                                OrderFileByBlackCatDto.class,
                                excelParam,
                                outputStream
                        );
                        String itemFileName;
                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = partition.get(i).size();
                        if (partition.size() > 1) {
                            itemFileName = fileNameTime + "本地仓-宅急便订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                        } else {
                            itemFileName = fileNameTime + "本地仓-宅急便订单-" + num1 + "件-" + size + "行.xlsx";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                    }
                } else if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(bo.getTrackIdByExport())) {
                    //佐川急便
                    ExcelUtils.exportExcel(
                            handlerExportBeforeForSagawa(dtoList, OrderFileBySagawaDto::getProductCode1),
                            OrderFileBySagawaDto.class,
                            excelParam,
                            bos
                    );
                    long num1 = dtoList.stream().filter(distinctByKey(OutboundOldExportDto::getOutboundNo)).count();
                    int size = dtoList.size();
                    exportZipDtoList.add(
                            new ExportZipDto(
                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.xlsx"),
                                    bos
                            )
                    );
                    ByteArrayOutputStream csvBos = new ByteArrayOutputStream();
                    CsvUtils.exportCsv(
                            csvParamWithoutHead,
                            OrderFileBySagawaDto.class,
                            handlerExportBeforeForSagawa(dtoList, OrderFileBySagawaDto::getProductCode1),
                            csvBos
                    );
                    exportZipDtoList.add(
                            new ExportZipDto(
                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.csv"),
                                    csvBos
                            )
                    );
                } else if (StaticDict.Order_CM_Track.KKKK.getValue().equals(bo.getTrackIdByExport())) {
                    //コンパクト
                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                            handlerExportBeforeForBlackCat(dtoList, OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
//                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < partition.size(); i++) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                partition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        ExcelUtils.exportExcel(
                                temp,
                                OrderFileByBlackCatDto.class,
                                excelParam,
                                outputStream
                        );
                        String itemFileName;
                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = partition.get(i).size();
                        if (partition.size() > 1) {
                            itemFileName = fileNameTime + "本地仓-コンパクト订单" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                        } else {
                            itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行.xlsx";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                    }
                } else {
                    //投函
                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                            handlerExportBeforeForBlackCat(dtoList, OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
//                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < partition.size(); i++) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                partition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        ExcelUtils.exportExcel(
                                temp,
                                OrderFileByBlackCatDto.class,
                                excelParam,
                                outputStream
                        );
                        String itemFileName;
                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = partition.get(i).size();
                        if (partition.size() > 1) {
                            itemFileName = fileNameTime + "本地仓-黑猫投函订单" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                        } else {
                            itemFileName = fileNameTime + "本地仓-黑猫投函订单-" + num1 + "件-" + size + "行.xlsx";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                    }
                }
            } else {
                fileName = "默认仓库渠道分单.zip";
                //按照默认仓库渠道分
                //先按仓库分，在循环中安渠道分
                Map<Long, List<OutboundOldExportDto>> orderByStorage = dtoList.stream()
                        .collect(Collectors.groupingBy(OutboundOldExportDto::getStorageId));
                for (Map.Entry<Long, List<OutboundOldExportDto>> orderByStorageEntry : orderByStorage.entrySet()) {
                    Long storageId = orderByStorageEntry.getKey();
                    List<OutboundOldExportDto> storageDataInfo = orderByStorageEntry.getValue();
                    if (Objects.nonNull(storageId) && StaticDict.CM_Storage.ThirdStorage.getValue().equals(storageId)) {
                        //排除佐川
                        storageDataInfo = storageDataInfo.stream()
                                .filter(o -> !StaticDict.Order_CM_Track.Sagawa.getValue().equals(o.getTrackId()))
                                .collect(Collectors.toList());
                        //订单全都为第三方仓库
                        List<OrderFileByThirdPartyDto> thirdPartyDtoList = BeanCopierUtils.listCopyMapper(
                                storageDataInfo,
                                OutboundOldExportDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        //宅急便分普通单0和次日达2
                        Map<Integer, List<OrderFileByThirdPartyDto>> typeMap = thirdPartyDtoList.stream()
                                .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                                .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getReserveFlag));
                        if (CollUtil.isNotEmpty(typeMap.get(1))) {
                            typeMap.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMap.get(1));
                            typeMap.remove(1);
                        }
                        //投函分一个黑猫投函和投函多件(非宅急便订单)
                        Map<Long, List<OrderFileByThirdPartyDto>> trackMap = thirdPartyDtoList.stream()
                                .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                                .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getTrackId));
                        //判断 普通单宅急便 + 单个黑猫投函 在10000行左右进行合并
                        if ((CollUtil.isEmpty(typeMap.get(0)) ? 0 : typeMap.get(0).size())
                            + (CollUtil.isEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                                ? 0
                                : trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                            < 10100) {
                            //合并的订单数据
                            //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                            List<OrderFileByThirdPartyDto> combineDailyList = new ArrayList<>(1000);
                            //次日达的一件投函
                            List<OrderFileByThirdPartyDto> yamatoOneNextDayList = new ArrayList<>(1000);
                            if (CollUtil.isNotEmpty(typeMap.get(0))) {
                                //日常单宅急便
                                combineDailyList.addAll(typeMap.get(0));
                                typeMap.remove(0);
                            }
                            if (CollUtil.isNotEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                                //日常单和预约黑猫投函
                                combineDailyList.addAll(
                                        trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                //次日达黑猫投函
                                yamatoOneNextDayList.addAll(
                                        trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                trackMap.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                            }
                            //前置处理订单数据
                            List<OrderFileByThirdPartyDto> dtos = handlerExportBeforeForThirdParty(combineDailyList, bo.getTrackIdByExport());
                            if (CollUtil.isNotEmpty(dtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dtos,
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dtos.size();
                                itemFileNum = fileNameTime + "三方倉-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                            List<OrderFileByThirdPartyDto> dailyDtos = handlerExportBeforeForThirdParty(yamatoOneNextDayList, bo.getTrackIdByExport());
                            if (CollUtil.isNotEmpty(dailyDtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dailyDtos,
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dailyDtos.size();
                                itemFileNum = fileNameTime + "三方倉-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }
                        for (Map.Entry<Integer, List<OrderFileByThirdPartyDto>> entry : typeMap.entrySet()) {
                            Integer reserveFlag = entry.getKey();
                            List<OrderFileByThirdPartyDto> sagawaList = entry.getValue();
                            List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                                    handlerExportBeforeForThirdParty(sagawaList, bo.getTrackIdByExport()),
                                    10000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }

                        for (Map.Entry<Long, List<OrderFileByThirdPartyDto>> entry : trackMap.entrySet()) {
                            Long track = entry.getKey();
                            List<OrderFileByThirdPartyDto> sendLetterList = entry.getValue();
                            List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                                    handlerExportBeforeForThirdParty(sendLetterList, bo.getTrackIdByExport()),
                                    10000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }

                        //=====================三方仓B2模板================
                        //宅急便分普通单0和次日达2
                        Map<Integer, List<OutboundOldExportDto>> typeMapB2 = storageDataInfo.stream()
                                .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                                .collect(Collectors.groupingBy(OutboundOldExportDto::getReserveFlag));
                        if (CollUtil.isNotEmpty(typeMapB2.get(1))) {
                            typeMapB2.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMapB2.get(1));
                            typeMapB2.remove(1);
                        }
                        //投函分一个黑猫投函和投函多件(非宅急便订单)
                        Map<Long, List<OutboundOldExportDto>> trackMapB2 = storageDataInfo.stream()
                                .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                                .collect(Collectors.groupingBy(OutboundOldExportDto::getTrackId));
                        //判断 普通单宅急便 + 单个黑猫投函 在1000行左右进行合并
                        if ((CollUtil.isEmpty(typeMapB2.get(0)) ? 0 : typeMapB2.get(0).size())
                            + (CollUtil.isEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                                ? 0
                                : trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                            < 1100) {
                            //合并的订单数据
                            //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                            List<OutboundOldExportDto> combineDailyList = new ArrayList<>(1000);
                            //次日达的一件投函
                            List<OutboundOldExportDto> yamatoOneNextDayList = new ArrayList<>(1000);
                            if (CollUtil.isNotEmpty(typeMapB2.get(0))) {
                                //日常单宅急便
                                combineDailyList.addAll(typeMapB2.get(0));
                                typeMapB2.remove(0);
                            }
                            if (CollUtil.isNotEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                                //日常单和预约黑猫投函
                                combineDailyList.addAll(
                                        trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                //次日达黑猫投函
                                yamatoOneNextDayList.addAll(
                                        trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                trackMapB2.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                            }
                            //前置处理订单数据
                            List<OrderFileByBlackCatDto> dtos = this.handlerExportBeforeForBlackCatB2(
                                    combineDailyList,
                                    bo.getTrackIdByExport(),
                                    OrderFileByBlackCatDto::getProductCode1
                            );
                            if (CollUtil.isNotEmpty(dtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dtos,
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dtos.size();
                                itemFileNum = fileNameTime + "三方倉B2模板-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                            List<OrderFileByBlackCatDto> dailyDtos = this.handlerExportBeforeForBlackCatB2(yamatoOneNextDayList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1);
                            if (CollUtil.isNotEmpty(dailyDtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dailyDtos,
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dailyDtos.size();
                                itemFileNum = fileNameTime + "三方倉B2模板-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }
                        for (Map.Entry<Integer, List<OutboundOldExportDto>> entry : typeMapB2.entrySet()) {
                            Integer reserveFlag = entry.getKey();
                            List<OutboundOldExportDto> sagawaList = entry.getValue();
                            List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatB2(sagawaList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }

                        for (Map.Entry<Long, List<OutboundOldExportDto>> entry : trackMapB2.entrySet()) {
                            Long track = entry.getKey();
                            List<OutboundOldExportDto> sendLetterList = entry.getValue();
                            List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatB2(sendLetterList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }
                        //=====================三方仓B2模板================

                        //封装api连接模板数据(排除预约单和次日达的宅急便订单)
                        List<OrderFileByApiDto> orderFileByApiDtos = BeanCopierUtils.listCopyMapper(
                                thirdPartyDtoList.stream()
                                        .filter(o -> !(o.getTrackId().equals(StaticDict.Order_CM_Track.YamatoZhai.getValue()) && !o.getReserveFlag().equals(0)))
                                        .collect(Collectors.toList()),
                                OrderFileByThirdPartyDto.class,
                                OrderFileByApiDto.class
                        );
                        //按照默认渠道分api数据
                        List<OrderFileByApiDto> apiBy300 = orderFileByApiDtos.stream()
                                .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderFileByApiDto.getTrackId()))
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(apiBy300)) {
                            List<List<OrderFileByApiDto>> partition = ListUtil.partition(handlerExportBeforeForApi(apiBy300, null), 5000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByApiDto.class,
                                        OrderFileByApiDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByApiDto.class,
                                        temp,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        }
                        if (apiBy300.size() < orderFileByApiDtos.size()) {
                            List<OrderFileByApiDto> apiBySendLetters = orderFileByApiDtos.stream()
                                    .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderFileByApiDto.getTrackId()))
                                    .collect(Collectors.toList());
                            if (CollUtil.isNotEmpty(apiBySendLetters)) {
                                List<List<OrderFileByApiDto>> partition = ListUtil.partition(handlerExportBeforeForApi(apiBySendLetters, null), 5000);
                                for (int i = 0; i < partition.size(); i++) {
                                    ByteArrayOutputStream apiBos = new ByteArrayOutputStream();
                                    List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                            partition.get(i),
                                            OrderFileByApiDto.class,
                                            OrderFileByApiDto.class
                                    );
                                    CsvUtils.exportCsv(
                                            csvParam,
                                            OrderFileByApiDto.class,
                                            temp,
                                            apiBos
                                    );
                                    String itemFileName;
                                    long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                                    int size = partition.get(i).size();
                                    if (partition.size() > 1) {
                                        itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                    } else {
                                        itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行.csv";
                                    }
                                    exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), apiBos));
                                }
                            }
                        }
                    } else if (Objects.nonNull(storageId) && StaticDict.CM_Storage.MyselfStorage.getValue().equals(storageId)) {
                        //全都为自有仓库
                        //自有仓库按照原订单渠道导出
                        Map<Long, List<OutboundOldExportDto>> map = new HashMap<>(8);
                        List<OutboundOldExportDto> temp1 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        (Objects.nonNull(orderCrossMallDo.getStorageId())
                                         && StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        ) || (Objects.nonNull(orderCrossMallDo.getTrackId())
                                              && (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderCrossMallDo.getTrackId())
                                                  || StaticDict.Order_CM_Track.YamatoMore.getValue().equals(orderCrossMallDo.getTrackId())
                                              ))
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp1)) {
                            map.put(StaticDict.Order_CM_Track.YamatoOne.getValue(), temp1);
                        }
                        List<OutboundOldExportDto> temp2 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        Objects.nonNull(orderCrossMallDo.getStorageId())
                                        && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        && Objects.nonNull(orderCrossMallDo.getTrackId())
                                        && StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderCrossMallDo.getTrackId())
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp2)) {
                            map.put(StaticDict.Order_CM_Track.YamatoZhai.getValue(), temp2);
                        }
                        List<OutboundOldExportDto> temp3 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        Objects.nonNull(orderCrossMallDo.getStorageId())
                                        && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        && Objects.nonNull(orderCrossMallDo.getTrackId())
                                        && StaticDict.Order_CM_Track.Sagawa.getValue().equals(orderCrossMallDo.getTrackId())
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp3)) {
                            map.put(StaticDict.Order_CM_Track.Sagawa.getValue(), temp3);
                        }
                        List<OutboundOldExportDto> temp4 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        Objects.nonNull(orderCrossMallDo.getStorageId())
                                        && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        && Objects.nonNull(orderCrossMallDo.getTrackId())
                                        && StaticDict.Order_CM_Track.KKKK.getValue().equals(orderCrossMallDo.getTrackId())
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp4)) {
                            map.put(StaticDict.Order_CM_Track.KKKK.getValue(), temp4);
                        }
                        map.forEach((trackId, value) -> {
                            try {
                                if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(trackId)) {
                                    //黑猫宅急便每1000条数据一个文件
                                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                            handlerExportBeforeForBlackCat(value, OrderFileByBlackCatDto::getProductCode1),
                                            1000
                                    );
                                    //同一管理番号同一个文件
//                                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                                    for (int i = 0; i < partition.size(); i++) {
                                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                                partition.get(i),
                                                OrderFileByBlackCatDto.class,
                                                OrderFileByBlackCatDto.class
                                        );
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ExcelUtils.exportExcel(
                                                temp,
                                                OrderFileByBlackCatDto.class,
                                                excelParam,
                                                outputStream
                                        );
                                        String itemFileName;
                                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                        int size = partition.get(i).size();
                                        if (partition.size() > 1) {
                                            itemFileName = fileNameTime + "本地仓-宅急便订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                        } else {
                                            itemFileName = fileNameTime + "本地仓-宅急便订单-" + num1 + "件-" + size + "行.xlsx";
                                        }
                                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                                    }
                                } else if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(trackId)) {
                                    //佐川急便
                                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                                    ExcelUtils.exportExcel(
                                            handlerExportBeforeForSagawa(value, OrderFileBySagawaDto::getProductCode1),
                                            OrderFileBySagawaDto.class,
                                            excelParam,
                                            bos
                                    );
                                    long num1 = value.stream().filter(distinctByKey(OutboundOldExportDto::getOutboundNo)).count();
                                    int size = value.size();
                                    exportZipDtoList.add(
                                            new ExportZipDto(
                                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.xlsx"),
                                                    bos
                                            )
                                    );
                                    ByteArrayOutputStream csvBos = new ByteArrayOutputStream();
                                    CsvUtils.exportCsv(
                                            csvParamWithoutHead,
                                            OrderFileBySagawaDto.class,
                                            handlerExportBeforeForSagawa(value, OrderFileBySagawaDto::getProductCode1),
                                            csvBos
                                    );
                                    exportZipDtoList.add(
                                            new ExportZipDto(
                                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.csv"),
                                                    csvBos
                                            )
                                    );
                                } else if (StaticDict.Order_CM_Track.KKKK.getValue().equals(trackId)) {
                                    //コンパクト
                                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                            handlerExportBeforeForBlackCat(value, OrderFileByBlackCatDto::getProductCode1),
                                            1000
                                    );
                                    //同一管理番号同一个文件
//                                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                                    for (int i = 0; i < partition.size(); i++) {
                                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                                partition.get(i),
                                                OrderFileByBlackCatDto.class,
                                                OrderFileByBlackCatDto.class
                                        );
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ExcelUtils.exportExcel(
                                                temp,
                                                OrderFileByBlackCatDto.class,
                                                excelParam,
                                                outputStream
                                        );
                                        String itemFileName;
                                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                        int size = partition.get(i).size();
                                        if (partition.size() > 1) {
                                            itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                        } else {
                                            itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行.xlsx";
                                        }
                                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                                    }
                                } else {
                                    //投函
                                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                            handlerExportBeforeForBlackCat(value, OrderFileByBlackCatDto::getProductCode1),
                                            1000
                                    );
                                    //同一管理番号同一个文件
//                                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                                    for (int i = 0; i < partition.size(); i++) {
                                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                                partition.get(i),
                                                OrderFileByBlackCatDto.class,
                                                OrderFileByBlackCatDto.class
                                        );
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ExcelUtils.exportExcel(
                                                temp,
                                                OrderFileByBlackCatDto.class,
                                                excelParam,
                                                outputStream
                                        );
                                        String itemFileName;
                                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                        int size = partition.get(i).size();
                                        if (partition.size() > 1) {
                                            itemFileName = fileNameTime + "本地仓-黑猫投函订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                        } else {
                                            itemFileName = fileNameTime + "本地仓-黑猫投函订单-" + num1 + "件-" + size + "行.xlsx";
                                        }
                                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                                    }
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });
                    }
                }
            }
        }
        response.setHeader("Content-Type", "application/x-zip-compressed");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setCharacterEncoding("Shift-JIS");
        for (ExportZipDto exportZipDto : exportZipDtoList) {
            //编写新的zip条目，并将流定位到条目数据的开头
            zos.putNextEntry(exportZipDto.getZipEntry());
            //写入zos
            exportZipDto.getBos().writeTo(zos);
            zos.closeEntry();
        }
        zos.finish();
        zos.close();
    }

    @Override
    public void exportOrderFileUseZipV2(NormalOrderOutboundQueryBo bo, HttpServletResponse response) throws IOException {
        if (Objects.nonNull(bo.getExcludeNotInTrackId()) && bo.getExcludeNotInTrackId()) {
            Long trackIdByExport = bo.getTrackIdByExport();
            if (Objects.nonNull(trackIdByExport)) {
                String channelCode = null;
                if (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_one";
                }
                if (StaticDict.Order_CM_Track.YamatoMore.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_more";
                }
                if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_zhai";
                }
                if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(trackIdByExport)) {
                    channelCode = "sawaga";
                }
                if (StaticDict.Order_CM_Track.KKKK.getValue().equals(trackIdByExport)) {
                    channelCode = "yamato_box";
                }
                LogisticsChannelDo channelDo = logisticsChannelService.lambdaQuery()
                        .eq(LogisticsChannelDo::getChannelCode, channelCode)
                        .last("limit 1")
                        .one();
                if (Objects.nonNull(channelDo)) {
                    bo.setLogisticsChannelIdList(Collections.singletonList(channelDo.getId()));
                }
            }
        }
        List<NormalOutboundVo> outboundVoList = outboundDao.getNormalListPage(bo);
        if (CollUtil.isEmpty(outboundVoList)) {
            throw new BizException(SysConstant.No_Data);
        }
        Map<Long, WarehouseDo> whIdMatch = warehouseService.lambdaQuery()
                .in(WarehouseDo::getId, outboundVoList.stream().map(NormalOutboundVo::getWhId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(WarehouseDo::getId, val -> val));
        Map<Long, LogisticsChannelDo> lcIdMatch = logisticsChannelService.lambdaQuery()
                .in(LogisticsChannelDo::getId, outboundVoList.stream().map(NormalOutboundVo::getLogisticsChannelId).collect(Collectors.toList())).list().stream().collect(Collectors.toMap(LogisticsChannelDo::getId, val -> val));
        List<OutboundOldExportDto> dtoList = new ArrayList<>();
        for (NormalOutboundVo outboundVo : outboundVoList) {
            OutboundOldExportDto dto = JSONUtil.toBean(JSONUtil.toJsonStr(outboundVo), OutboundOldExportDto.class);
            WarehouseDo warehouseDo = whIdMatch.get(outboundVo.getWhId());
            if (warehouseDo == null) {
                dto.setStorageId(StaticDict.CM_Storage.MyselfStorage.getValue());
            } else {
                dto.setStorageId(warehouseDo.getWarehouseType().equals(0) ? StaticDict.CM_Storage.MyselfStorage.getValue() : StaticDict.CM_Storage.ThirdStorage.getValue());
            }
            LogisticsChannelDo channelDo = lcIdMatch.get(outboundVo.getLogisticsChannelId());
            if (Objects.nonNull(channelDo)) {
                switch (channelDo.getChannelCode()) {
                    case "yamato_one":
                        dto.setTrackId(StaticDict.Order_CM_Track.YamatoOne.getValue());
                        break;
                    case "yamato_more":
                        dto.setTrackId(StaticDict.Order_CM_Track.YamatoMore.getValue());
                        break;
                    case "yamato_zhai":
                        dto.setTrackId(StaticDict.Order_CM_Track.YamatoZhai.getValue());
                        break;
                    case "sawaga":
                        dto.setTrackId(StaticDict.Order_CM_Track.Sagawa.getValue());
                        break;
                    case "yamato_box":
                        dto.setTrackId(StaticDict.Order_CM_Track.KKKK.getValue());
                        break;
                    default:
                        dto.setTrackId(null);
                }
            } else {
                dto.setTrackId(null);
            }
            dtoList.add(dto);
        }
        String fileNameTime = DateUtil.format(new Date(), "yyyyMMdd-HH時");
        //导出zip的名字根据情况命名
        String fileName;
        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
        zos.setLevel(1);
        //Excel文件导出配置
        ExportParams excelParam = new ExportParams();
        excelParam.setType(ExcelType.XSSF);
        excelParam.setStyle(ExcelExportTitleStyle.class);
        //Csv文件导出配置（去标题）
        CsvExportParams csvParamWithoutHead = new CsvExportParams();
        csvParamWithoutHead.setCreateHeadRows(false);
        csvParamWithoutHead.setEncoding("Shift-JIS");
        csvParamWithoutHead.setTextMark("");
        //Csv文件导出配置
        CsvExportParams csvParam = new CsvExportParams();
        csvParam.setEncoding("Shift-JIS");
        csvParam.setTextMark("");
        //所有输出流及zip文件都放在这个集合里面
        List<ExportZipDto> exportZipDtoList = new ArrayList<>(20);
        //添加未分单的预约单
        List<OutboundOldExportDto> reserveList = dtoList.stream()
                .filter(o -> o.getReserveFlag().equals(1) && Objects.isNull(o.getTrackId()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(reserveList)) {
            List<OrderFileByReserveDto> orderFileByReserveDtos = JSONUtil.toList(JSONUtil.toJsonStr(reserveList), OrderFileByReserveDto.class);
            //根据预约时间段分文件
            orderFileByReserveDtos.stream().map(OrderFileByReserveDto::getReserveBeginTime).distinct().forEach(item -> {
                List<OrderFileByReserveDto> list = orderFileByReserveDtos.stream()
                        .filter(o -> o.getReserveBeginTime().compareTo(item) == 0)
                        .collect(Collectors.toList());
                OrderFileByReserveDto tempDto = list.get(0);
                String timeBand = DateUtil.format(tempDto.getReserveBeginTime(), "MM.dd-") +
                                  DateUtil.format(tempDto.getReserveEndTime(), "MM.dd");
                List<List<OrderFileByReserveDto>> partition = ListUtil.partition(list, 5000);
                for (int i = 0; i < partition.size(); i++) {
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    List<OrderFileByReserveDto> temp = BeanCopierUtils.listCopyMapper(
                            partition.get(i),
                            OrderFileByReserveDto.class,
                            OrderFileByReserveDto.class
                    );
                    CsvUtils.exportCsv(csvParam, OrderFileByReserveDto.class, temp, outputStream);
                    String itemFileNum;
                    long num = partition.get(i).stream().filter(distinctByKey(OrderFileByReserveDto::getOutboundNo)).count();
                    if (partition.size() > 1) {
                        itemFileNum = fileNameTime + "予約" + timeBand + "-" + num + "(" + (i + 1) + ").csv";
                    } else {
                        itemFileNum = fileNameTime + "予約" + timeBand + "-" + num + ".csv";
                    }
                    exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), outputStream));
                }
            });
        }
        //未进行导出操作的数据
        List<OutboundOldExportDto> noOperateList = dtoList.stream()
                .filter(o -> !o.getReserveFlag().equals(1) && Objects.isNull(o.getTrackId()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(noOperateList)) {
            List<OrderFileByNoOperateDto> orderFileByNoOperateDtos = JSONUtil.toList(JSONUtil.toJsonStr(noOperateList), OrderFileByNoOperateDto.class);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            CsvUtils.exportCsv(csvParam, OrderFileByNoOperateDto.class, orderFileByNoOperateDtos, outputStream);
            String itemFile = fileNameTime + "指定されていないチャネル-" + orderFileByNoOperateDtos.size() + ".csv";
            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFile), outputStream));
        }
        fileName = "第三方仓库订单.zip";
        //数据中含有未分单的预约单的订单，需要排除掉
        dtoList = dtoList.stream()
                .filter(o -> Objects.nonNull(o.getTrackId()))
                .collect(Collectors.toList());
        if (CollUtil.isNotEmpty(dtoList)) {
            //手动指定为三方仓库,渠道在第三方仓库前置方法内强制修改原有订单数据
            if (StaticDict.CM_Storage.ThirdStorage.getValue().equals(bo.getWhIdByExport())) {
                fileName = "第三方仓库订单.zip";
                //排除佐川
                dtoList = dtoList.stream()
                        .filter(o -> !StaticDict.Order_CM_Track.Sagawa.getValue().equals(o.getTrackId()))
                        .collect(Collectors.toList());
                List<OrderFileByThirdPartyDto> thirdPartyDtoList = BeanCopierUtils.listCopyMapper(
                        dtoList,
                        OutboundOldExportDto.class,
                        OrderFileByThirdPartyDto.class
                );
                //宅急便分普通单0和次日达2
                Map<Integer, List<OrderFileByThirdPartyDto>> typeMap = thirdPartyDtoList.stream()
                        .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                        .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getReserveFlag));
                //投函分一个黑猫投函和投函多件(非宅急便订单)
                Map<Long, List<OrderFileByThirdPartyDto>> trackMap = thirdPartyDtoList.stream()
                        .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                        .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getTrackId));
                if (CollUtil.isNotEmpty(typeMap.get(1))) {
                    typeMap.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMap.get(1));
                    typeMap.remove(1);
                }
                //判断 普通单宅急便 + 单个黑猫投函 在10000行左右进行合并
                if ((CollUtil.isEmpty(typeMap.get(0)) ? 0 : typeMap.get(0).size())
                    + (CollUtil.isEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                        ? 0
                        : trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                    < 10100) {
                    //合并的订单数据
                    //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                    List<OrderFileByThirdPartyDto> combineDailyList = new ArrayList<>(1000);
                    //次日达的一件投函
                    List<OrderFileByThirdPartyDto> yamatoOneNextDayList = new ArrayList<>(1000);
                    if (CollUtil.isNotEmpty(typeMap.get(0))) {
                        //日常单宅急便
                        combineDailyList.addAll(typeMap.get(0));
                        typeMap.remove(0);
                    }
                    if (CollUtil.isNotEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                        //日常单和预约黑猫投函
                        combineDailyList.addAll(
                                trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        //次日达黑猫投函
                        yamatoOneNextDayList.addAll(
                                trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        trackMap.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                    }
                    //前置处理订单数据
                    List<OrderFileByThirdPartyDto> dtos = this.handlerExportBeforeForThirdPartyV2(combineDailyList, bo.getTrackIdByExport());
                    if (CollUtil.isNotEmpty(dtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dtos,
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dtos.size();
                        itemFileNum = fileNameTime + "三方倉-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                    List<OrderFileByThirdPartyDto> dailyDtos = this.handlerExportBeforeForThirdPartyV2(yamatoOneNextDayList, bo.getTrackIdByExport());
                    if (CollUtil.isNotEmpty(dailyDtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dailyDtos,
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dailyDtos.size();
                        itemFileNum = fileNameTime + "三方倉-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }
                for (Map.Entry<Integer, List<OrderFileByThirdPartyDto>> entry : typeMap.entrySet()) {
                    Integer reserveFlag = entry.getKey();
                    List<OrderFileByThirdPartyDto> sagawaList = entry.getValue();
                    List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                            this.handlerExportBeforeForThirdPartyV2(sagawaList, bo.getTrackIdByExport()),
                            10000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }

                for (Map.Entry<Long, List<OrderFileByThirdPartyDto>> entry : trackMap.entrySet()) {
                    Long track = entry.getKey();
                    List<OrderFileByThirdPartyDto> sendLetterList = entry.getValue();
                    List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                            this.handlerExportBeforeForThirdPartyV2(sendLetterList, bo.getTrackIdByExport()),
                            10000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByThirdPartyDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByThirdPartyDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }

                //=====================三方仓B2模板================
                //宅急便分普通单0和次日达2
                Map<Integer, List<OutboundOldExportDto>> typeMapB2 = dtoList.stream()
                        .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                        .collect(Collectors.groupingBy(OutboundOldExportDto::getReserveFlag));
                //投函分一个黑猫投函和投函多件(非宅急便订单)
                Map<Long, List<OutboundOldExportDto>> trackMapB2 = dtoList.stream()
                        .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                        .collect(Collectors.groupingBy(OutboundOldExportDto::getTrackId));
                if (CollUtil.isNotEmpty(typeMapB2.get(1))) {
                    typeMapB2.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMapB2.get(1));
                    typeMapB2.remove(1);
                }
                //判断 普通单宅急便 + 单个黑猫投函 在1000行左右进行合并
                if ((CollUtil.isEmpty(typeMapB2.get(0)) ? 0 : typeMapB2.get(0).size())
                    + (CollUtil.isEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                        ? 0
                        : trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                    < 1100) {
                    //合并的订单数据
                    //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                    List<OutboundOldExportDto> combineDailyList = new ArrayList<>(1000);
                    //次日达的一件投函
                    List<OutboundOldExportDto> yamatoOneNextDayList = new ArrayList<>(1000);
                    if (CollUtil.isNotEmpty(typeMapB2.get(0))) {
                        //日常单宅急便
                        combineDailyList.addAll(typeMapB2.get(0));
                        typeMapB2.remove(0);
                    }
                    if (CollUtil.isNotEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                        //日常单和预约黑猫投函
                        combineDailyList.addAll(
                                trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        //次日达黑猫投函
                        yamatoOneNextDayList.addAll(
                                trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                        .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                        );
                        trackMapB2.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                    }
                    //前置处理订单数据
                    List<OrderFileByBlackCatDto> dtos = this.handlerExportBeforeForBlackCatB2(
                            combineDailyList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1);
                    if (CollUtil.isNotEmpty(dtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dtos,
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dtos.size();
                        itemFileNum = fileNameTime + "三方倉B2模板-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                    List<OrderFileByBlackCatDto> dailyDtos = this.handlerExportBeforeForBlackCatB2(
                            yamatoOneNextDayList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1);
                    if (CollUtil.isNotEmpty(dailyDtos)) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dailyDtos,
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dailyDtos.size();
                        itemFileNum = fileNameTime + "三方倉B2模板-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }
                for (Map.Entry<Integer, List<OutboundOldExportDto>> entry : typeMapB2.entrySet()) {
                    Integer reserveFlag = entry.getKey();
                    List<OutboundOldExportDto> sagawaList = entry.getValue();
                    List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatB2(
                                    sagawaList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }

                for (Map.Entry<Long, List<OutboundOldExportDto>> entry : trackMapB2.entrySet()) {
                    Long track = entry.getKey();
                    List<OutboundOldExportDto> sendLetterList = entry.getValue();
                    List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatB2(
                                    sendLetterList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
                    dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < dataPartition.size(); i++) {
                        ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                dataPartition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        CsvUtils.exportCsv(
                                csvParam,
                                OrderFileByBlackCatDto.class,
                                temp,
                                thirdPartyBos
                        );
                        String itemFileNum;
                        long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = dataPartition.get(i).size();
                        if (dataPartition.size() > 1) {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                        } else {
                            itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                    }
                }
                //=====================三方仓B2模板================

                //封装api连接模板数据(排除预约单和次日达的宅急便订单)
                List<OrderFileByApiDto> orderFileByApiDtos = BeanCopierUtils.listCopyMapper(
                        thirdPartyDtoList.stream()
                                .filter(o -> !(o.getTrackId().equals(StaticDict.Order_CM_Track.YamatoZhai.getValue()) && !o.getReserveFlag().equals(0)))
                                .collect(Collectors.toList()),
                        OrderFileByThirdPartyDto.class,
                        OrderFileByApiDto.class
                );
                //指定渠道，只有一个api数据文件
                if (Objects.nonNull(bo.getTrackIdByExport())) {
                    List<List<OrderFileByApiDto>> partition = ListUtil.partition(this.handlerExportBeforeForApiV2(orderFileByApiDtos, bo.getTrackIdByExport()), 5000);
                    if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(bo.getTrackIdByExport())) {
                        //宅急便
                        for (int i = 0; i < partition.size(); i++) {
                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                    partition.get(i),
                                    OrderFileByApiDto.class,
                                    OrderFileByApiDto.class
                            );
                            CsvUtils.exportCsv(
                                    csvParam,
                                    OrderFileByApiDto.class,
                                    temp,
                                    outputStream
                            );
                            String itemFileName;
                            long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                            int size = partition.get(i).size();
                            if (partition.size() > 1) {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                            } else {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行.csv";
                            }
                            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                        }
                    } else if (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(bo.getTrackIdByExport())) {
                        //三方仓-黑猫投函api(不包括投函多件)
                        for (int i = 0; i < partition.size(); i++) {
                            ByteArrayOutputStream apiBos = new ByteArrayOutputStream();
                            List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                    partition.get(i),
                                    OrderFileByApiDto.class,
                                    OrderFileByApiDto.class
                            );
                            CsvUtils.exportCsv(
                                    csvParam,
                                    OrderFileByApiDto.class,
                                    temp,
                                    apiBos
                            );
                            String itemFileName;
                            long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                            int size = partition.get(i).size();
                            if (partition.size() > 1) {
                                itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                            } else {
                                itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行.csv";
                            }
                            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), apiBos));
                        }
                    }
                } else {
                    //按照默认渠道分api数据
                    List<OrderFileByApiDto> apiBy300 = orderFileByApiDtos.stream()
                            .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderFileByApiDto.getTrackId()))
                            .collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(apiBy300)) {
                        List<List<OrderFileByApiDto>> partition = ListUtil.partition(this.handlerExportBeforeForApiV2(apiBy300, null), 5000);
                        for (int i = 0; i < partition.size(); i++) {
                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                    partition.get(i),
                                    OrderFileByApiDto.class,
                                    OrderFileByApiDto.class
                            );
                            CsvUtils.exportCsv(
                                    csvParam,
                                    OrderFileByApiDto.class,
                                    temp,
                                    outputStream
                            );
                            String itemFileName;
                            long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                            int size = partition.get(i).size();
                            if (partition.size() > 1) {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                            } else {
                                itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行.csv";
                            }
                            exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                        }
                    }
                    if (apiBy300.size() < orderFileByApiDtos.size()) {
                        List<OrderFileByApiDto> apiBySendLetters = orderFileByApiDtos.stream()
                                .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderFileByApiDto.getTrackId()))
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(apiBySendLetters)) {
                            List<List<OrderFileByApiDto>> partition = ListUtil.partition(this.handlerExportBeforeForApiV2(apiBySendLetters, null), 5000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream apiBos = new ByteArrayOutputStream();
                                List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByApiDto.class,
                                        OrderFileByApiDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByApiDto.class,
                                        temp,
                                        apiBos
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), apiBos));
                            }
                        }
                    }
                }
            } else if (StaticDict.CM_Storage.MyselfStorage.getValue().equals(bo.getWhIdByExport())
                       && Objects.isNull(bo.getTrackIdByExport())) {
                //本地仓没有指定渠道，按照原订单渠道导出
                fileName = "本地仓库订单.zip";
                Map<Long, List<OutboundOldExportDto>> map = new HashMap<>(8);
                List<OutboundOldExportDto> temp1 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                (Objects.nonNull(orderCrossMallDo.getStorageId())
                                 && StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                ) || (Objects.nonNull(orderCrossMallDo.getTrackId())
                                      && (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderCrossMallDo.getTrackId())
                                          || StaticDict.Order_CM_Track.YamatoMore.getValue().equals(orderCrossMallDo.getTrackId())
                                      ))
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp1)) {
                    map.put(StaticDict.CM_Storage.ThirdStorage.getValue(), temp1);
                }
                List<OutboundOldExportDto> temp2 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                Objects.nonNull(orderCrossMallDo.getStorageId())
                                && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                && Objects.nonNull(orderCrossMallDo.getTrackId())
                                && StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderCrossMallDo.getTrackId())
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp2)) {
                    map.put(StaticDict.Order_CM_Track.YamatoZhai.getValue(), temp2);
                }
                List<OutboundOldExportDto> temp3 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                Objects.nonNull(orderCrossMallDo.getStorageId())
                                && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                && Objects.nonNull(orderCrossMallDo.getTrackId())
                                && StaticDict.Order_CM_Track.Sagawa.getValue().equals(orderCrossMallDo.getTrackId())
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp3)) {
                    map.put(StaticDict.Order_CM_Track.Sagawa.getValue(), temp3);
                }
                List<OutboundOldExportDto> temp4 = dtoList.stream()
                        .filter(orderCrossMallDo ->
                                Objects.nonNull(orderCrossMallDo.getStorageId())
                                && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                && Objects.nonNull(orderCrossMallDo.getTrackId())
                                && StaticDict.Order_CM_Track.KKKK.getValue().equals(orderCrossMallDo.getTrackId())
                        )
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(temp4)) {
                    map.put(StaticDict.Order_CM_Track.KKKK.getValue(), temp4);
                }
                map.forEach((trackId, value) -> {
                    try {
                        if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(trackId)) {
                            //黑猫宅急便每1000条数据一个文件
                            List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatV2(value, OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
//                        partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                ExcelUtils.exportExcel(
                                        temp,
                                        OrderFileByBlackCatDto.class,
                                        excelParam,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "本地仓-佐川急便订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                } else {
                                    itemFileName = fileNameTime + "本地仓-佐川急便订单-" + num1 + "件-" + size + "行.xlsx";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        } else if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(trackId)) {
                            //佐川急便
                            ByteArrayOutputStream bos = new ByteArrayOutputStream();
                            ExcelUtils.exportExcel(
                                    this.handlerExportBeforeForSagawaV2(value, OrderFileBySagawaDto::getProductCode1),
                                    OrderFileBySagawaDto.class,
                                    excelParam,
                                    bos
                            );
                            long num1 = value.stream().filter(distinctByKey(OutboundOldExportDto::getOutboundNo)).count();
                            int size = value.size();
                            exportZipDtoList.add(
                                    new ExportZipDto(
                                            new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.xlsx"),
                                            bos
                                    )
                            );
                            ByteArrayOutputStream csvBos = new ByteArrayOutputStream();
                            CsvUtils.exportCsv(
                                    csvParamWithoutHead,
                                    OrderFileBySagawaDto.class,
                                    this.handlerExportBeforeForSagawaV2(value, OrderFileBySagawaDto::getProductCode1),
                                    csvBos
                            );
                            exportZipDtoList.add(
                                    new ExportZipDto(
                                            new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.csv"),
                                            csvBos
                                    )
                            );
                        } else if (StaticDict.Order_CM_Track.KKKK.getValue().equals(trackId)) {
                            //コンパクト
                            List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatV2(value, OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
//                        partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                ExcelUtils.exportExcel(
                                        temp,
                                        OrderFileByBlackCatDto.class,
                                        excelParam,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                } else {
                                    itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行.xlsx";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        } else {
                            //投函
                            List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatV2(value, OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
//                        partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                ExcelUtils.exportExcel(
                                        temp,
                                        OrderFileByBlackCatDto.class,
                                        excelParam,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "本地仓-佐川投函订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                } else {
                                    itemFileName = fileNameTime + "本地仓-佐川投函订单-" + num1 + "件-" + size + "行.xlsx";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            } else if (Objects.nonNull(bo.getTrackIdByExport())) {
                //本地仓库且指定渠道
                fileName = "本地仓订单.zip";
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                //手动指定渠道，按照指定渠道导出，不管原订单渠道
                if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(bo.getTrackIdByExport())) {
                    //黑猫宅急便每1000条数据一个文件
                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatV2(dtoList, OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
//                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < partition.size(); i++) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                partition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        ExcelUtils.exportExcel(
                                temp,
                                OrderFileByBlackCatDto.class,
                                excelParam,
                                outputStream
                        );
                        String itemFileName;
                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = partition.get(i).size();
                        if (partition.size() > 1) {
                            itemFileName = fileNameTime + "本地仓-佐川急便订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                        } else {
                            itemFileName = fileNameTime + "本地仓-佐川急便订单-" + num1 + "件-" + size + "行.xlsx";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                    }
                } else if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(bo.getTrackIdByExport())) {
                    //佐川急便
                    ExcelUtils.exportExcel(
                            this.handlerExportBeforeForSagawaV2(dtoList, OrderFileBySagawaDto::getProductCode1),
                            OrderFileBySagawaDto.class,
                            excelParam,
                            bos
                    );
                    long num1 = dtoList.stream().filter(distinctByKey(OutboundOldExportDto::getOutboundNo)).count();
                    int size = dtoList.size();
                    exportZipDtoList.add(
                            new ExportZipDto(
                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.xlsx"),
                                    bos
                            )
                    );
                    ByteArrayOutputStream csvBos = new ByteArrayOutputStream();
                    CsvUtils.exportCsv(
                            csvParamWithoutHead,
                            OrderFileBySagawaDto.class,
                            this.handlerExportBeforeForSagawaV2(dtoList, OrderFileBySagawaDto::getProductCode1),
                            csvBos
                    );
                    exportZipDtoList.add(
                            new ExportZipDto(
                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.csv"),
                                    csvBos
                            )
                    );
                } else if (StaticDict.Order_CM_Track.KKKK.getValue().equals(bo.getTrackIdByExport())) {
                    //コンパクト
                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatV2(dtoList, OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
//                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < partition.size(); i++) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                partition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        ExcelUtils.exportExcel(
                                temp,
                                OrderFileByBlackCatDto.class,
                                excelParam,
                                outputStream
                        );
                        String itemFileName;
                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = partition.get(i).size();
                        if (partition.size() > 1) {
                            itemFileName = fileNameTime + "本地仓-コンパクト订单" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                        } else {
                            itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行.xlsx";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                    }
                } else {
                    //投函
                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                            this.handlerExportBeforeForBlackCatV2(dtoList, OrderFileByBlackCatDto::getProductCode1),
                            1000
                    );
                    //同一管理番号同一个文件
//                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                    for (int i = 0; i < partition.size(); i++) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                partition.get(i),
                                OrderFileByBlackCatDto.class,
                                OrderFileByBlackCatDto.class
                        );
                        ExcelUtils.exportExcel(
                                temp,
                                OrderFileByBlackCatDto.class,
                                excelParam,
                                outputStream
                        );
                        String itemFileName;
                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                        int size = partition.get(i).size();
                        if (partition.size() > 1) {
                            itemFileName = fileNameTime + "本地仓-佐川投函订单" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                        } else {
                            itemFileName = fileNameTime + "本地仓-佐川投函订单-" + num1 + "件-" + size + "行.xlsx";
                        }
                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                    }
                }
            } else {
                fileName = "默认仓库渠道分单.zip";
                //按照默认仓库渠道分
                //先按仓库分，在循环中安渠道分
                Map<Long, List<OutboundOldExportDto>> orderByStorage = dtoList.stream()
                        .collect(Collectors.groupingBy(OutboundOldExportDto::getStorageId));
                for (Map.Entry<Long, List<OutboundOldExportDto>> orderByStorageEntry : orderByStorage.entrySet()) {
                    Long storageId = orderByStorageEntry.getKey();
                    List<OutboundOldExportDto> storageDataInfo = orderByStorageEntry.getValue();
                    if (Objects.nonNull(storageId) && StaticDict.CM_Storage.ThirdStorage.getValue().equals(storageId)) {
                        //排除佐川
                        storageDataInfo = storageDataInfo.stream()
                                .filter(o -> !StaticDict.Order_CM_Track.Sagawa.getValue().equals(o.getTrackId()))
                                .collect(Collectors.toList());
                        //订单全都为第三方仓库
                        List<OrderFileByThirdPartyDto> thirdPartyDtoList = BeanCopierUtils.listCopyMapper(
                                storageDataInfo,
                                OutboundOldExportDto.class,
                                OrderFileByThirdPartyDto.class
                        );
                        //宅急便分普通单0和次日达2
                        Map<Integer, List<OrderFileByThirdPartyDto>> typeMap = thirdPartyDtoList.stream()
                                .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                                .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getReserveFlag));
                        if (CollUtil.isNotEmpty(typeMap.get(1))) {
                            typeMap.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMap.get(1));
                            typeMap.remove(1);
                        }
                        //投函分一个黑猫投函和投函多件(非宅急便订单)
                        Map<Long, List<OrderFileByThirdPartyDto>> trackMap = thirdPartyDtoList.stream()
                                .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                                .collect(Collectors.groupingBy(OrderFileByThirdPartyDto::getTrackId));
                        //判断 普通单宅急便 + 单个黑猫投函 在10000行左右进行合并
                        if ((CollUtil.isEmpty(typeMap.get(0)) ? 0 : typeMap.get(0).size())
                            + (CollUtil.isEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                                ? 0
                                : trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                            < 10100) {
                            //合并的订单数据
                            //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                            List<OrderFileByThirdPartyDto> combineDailyList = new ArrayList<>(1000);
                            //次日达的一件投函
                            List<OrderFileByThirdPartyDto> yamatoOneNextDayList = new ArrayList<>(1000);
                            if (CollUtil.isNotEmpty(typeMap.get(0))) {
                                //日常单宅急便
                                combineDailyList.addAll(typeMap.get(0));
                                typeMap.remove(0);
                            }
                            if (CollUtil.isNotEmpty(trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                                //日常单和预约黑猫投函
                                combineDailyList.addAll(
                                        trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                //次日达黑猫投函
                                yamatoOneNextDayList.addAll(
                                        trackMap.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                trackMap.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                            }
                            //前置处理订单数据
                            List<OrderFileByThirdPartyDto> dtos = this.handlerExportBeforeForThirdPartyV2(combineDailyList, bo.getTrackIdByExport());
                            if (CollUtil.isNotEmpty(dtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dtos,
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dtos.size();
                                itemFileNum = fileNameTime + "三方倉-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                            List<OrderFileByThirdPartyDto> dailyDtos = this.handlerExportBeforeForThirdPartyV2(yamatoOneNextDayList, bo.getTrackIdByExport());
                            if (CollUtil.isNotEmpty(dailyDtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dailyDtos,
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dailyDtos.size();
                                itemFileNum = fileNameTime + "三方倉-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }
                        for (Map.Entry<Integer, List<OrderFileByThirdPartyDto>> entry : typeMap.entrySet()) {
                            Integer reserveFlag = entry.getKey();
                            List<OrderFileByThirdPartyDto> sagawaList = entry.getValue();
                            List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                                    this.handlerExportBeforeForThirdPartyV2(sagawaList, bo.getTrackIdByExport()),
                                    10000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }

                        for (Map.Entry<Long, List<OrderFileByThirdPartyDto>> entry : trackMap.entrySet()) {
                            Long track = entry.getKey();
                            List<OrderFileByThirdPartyDto> sendLetterList = entry.getValue();
                            List<List<OrderFileByThirdPartyDto>> dataPartition = ListUtil.partition(
                                    this.handlerExportBeforeForThirdPartyV2(sendLetterList, bo.getTrackIdByExport()),
                                    10000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByThirdPartyDto::getOutboundNo, 10000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByThirdPartyDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByThirdPartyDto.class,
                                        OrderFileByThirdPartyDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByThirdPartyDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByThirdPartyDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }

                        //=====================三方仓B2模板================
                        //宅急便分普通单0和次日达2
                        Map<Integer, List<OutboundOldExportDto>> typeMapB2 = storageDataInfo.stream()
                                .filter(t -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(t.getTrackId()))
                                .collect(Collectors.groupingBy(OutboundOldExportDto::getReserveFlag));
                        if (CollUtil.isNotEmpty(typeMapB2.get(1))) {
                            typeMapB2.computeIfAbsent(0, k -> new ArrayList<>()).addAll(typeMapB2.get(1));
                            typeMapB2.remove(1);
                        }
                        //投函分一个黑猫投函和投函多件(非宅急便订单)
                        Map<Long, List<OutboundOldExportDto>> trackMapB2 = storageDataInfo.stream()
                                .filter(o -> !StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(o.getTrackId()))
                                .collect(Collectors.groupingBy(OutboundOldExportDto::getTrackId));
                        //判断 普通单宅急便 + 单个黑猫投函 在1000行左右进行合并
                        if ((CollUtil.isEmpty(typeMapB2.get(0)) ? 0 : typeMapB2.get(0).size())
                            + (CollUtil.isEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))
                                ? 0
                                : trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).size())
                            < 1100) {
                            //合并的订单数据
                            //避免订单数据重复使用（包含一件投函和宅急便的日常单）
                            List<OutboundOldExportDto> combineDailyList = new ArrayList<>(1000);
                            //次日达的一件投函
                            List<OutboundOldExportDto> yamatoOneNextDayList = new ArrayList<>(1000);
                            if (CollUtil.isNotEmpty(typeMapB2.get(0))) {
                                //日常单宅急便
                                combineDailyList.addAll(typeMapB2.get(0));
                                typeMapB2.remove(0);
                            }
                            if (CollUtil.isNotEmpty(trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()))) {
                                //日常单和预约黑猫投函
                                combineDailyList.addAll(
                                        trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> !item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                //次日达黑猫投函
                                yamatoOneNextDayList.addAll(
                                        trackMapB2.get(StaticDict.Order_CM_Track.YamatoOne.getValue()).stream()
                                                .filter(item -> item.getReserveFlag().equals(2)).collect(Collectors.toList())
                                );
                                trackMapB2.remove(StaticDict.Order_CM_Track.YamatoOne.getValue());
                            }
                            //前置处理订单数据
                            List<OrderFileByBlackCatDto> dtos = this.handlerExportBeforeForBlackCatB2(
                                    combineDailyList,
                                    bo.getTrackIdByExport(),
                                    OrderFileByBlackCatDto::getProductCode1
                            );
                            if (CollUtil.isNotEmpty(dtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dtos,
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dtos.size();
                                itemFileNum = fileNameTime + "三方倉B2模板-日常-1個ネコ+宅-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                            List<OrderFileByBlackCatDto> dailyDtos = this.handlerExportBeforeForBlackCatB2(
                                    yamatoOneNextDayList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1);
                            if (CollUtil.isNotEmpty(dailyDtos)) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dailyDtos,
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dailyDtos.stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dailyDtos.size();
                                itemFileNum = fileNameTime + "三方倉B2模板-翌日達-1個ネコ-" + num1 + "件-" + size + "行.csv";
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }
                        for (Map.Entry<Integer, List<OutboundOldExportDto>> entry : typeMapB2.entrySet()) {
                            Integer reserveFlag = entry.getKey();
                            List<OutboundOldExportDto> sagawaList = entry.getValue();
                            List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatB2(sagawaList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Order_Type.getText(reserveFlag) + "-宅-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }

                        for (Map.Entry<Long, List<OutboundOldExportDto>> entry : trackMapB2.entrySet()) {
                            Long track = entry.getKey();
                            List<OutboundOldExportDto> sendLetterList = entry.getValue();
                            List<List<OrderFileByBlackCatDto>> dataPartition = ListUtil.partition(
                                    this.handlerExportBeforeForBlackCatB2(sendLetterList, bo.getTrackIdByExport(), OrderFileByBlackCatDto::getProductCode1),
                                    1000
                            );
                            //同一管理番号同一个文件
                            dataPartition = sameOrderNumberSameList(dataPartition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                            for (int i = 0; i < dataPartition.size(); i++) {
                                ByteArrayOutputStream thirdPartyBos = new ByteArrayOutputStream();
                                List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                        dataPartition.get(i),
                                        OrderFileByBlackCatDto.class,
                                        OrderFileByBlackCatDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByBlackCatDto.class,
                                        temp,
                                        thirdPartyBos
                                );
                                String itemFileNum;
                                long num1 = dataPartition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                int size = dataPartition.get(i).size();
                                if (dataPartition.size() > 1) {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileNum = fileNameTime + "三方倉B2模板-" + StaticDict.Order_CM_Track.getText(track) + "-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileNum), thirdPartyBos));
                            }
                        }
                        //=====================三方仓B2模板================

                        //封装api连接模板数据(排除预约单和次日达的宅急便订单)
                        List<OrderFileByApiDto> orderFileByApiDtos = BeanCopierUtils.listCopyMapper(
                                thirdPartyDtoList.stream()
                                        .filter(o -> !(o.getTrackId().equals(StaticDict.Order_CM_Track.YamatoZhai.getValue()) && !o.getReserveFlag().equals(0)))
                                        .collect(Collectors.toList()),
                                OrderFileByThirdPartyDto.class,
                                OrderFileByApiDto.class
                        );
                        //按照默认渠道分api数据
                        List<OrderFileByApiDto> apiBy300 = orderFileByApiDtos.stream()
                                .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderFileByApiDto.getTrackId()))
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(apiBy300)) {
                            List<List<OrderFileByApiDto>> partition = ListUtil.partition(this.handlerExportBeforeForApiV2(apiBy300, null), 5000);
                            for (int i = 0; i < partition.size(); i++) {
                                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                        partition.get(i),
                                        OrderFileByApiDto.class,
                                        OrderFileByApiDto.class
                                );
                                CsvUtils.exportCsv(
                                        csvParam,
                                        OrderFileByApiDto.class,
                                        temp,
                                        outputStream
                                );
                                String itemFileName;
                                long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                                int size = partition.get(i).size();
                                if (partition.size() > 1) {
                                    itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                } else {
                                    itemFileName = fileNameTime + "三方倉-日常-宅-API-" + num1 + "件-" + size + "行.csv";
                                }
                                exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                            }
                        }
                        if (apiBy300.size() < orderFileByApiDtos.size()) {
                            List<OrderFileByApiDto> apiBySendLetters = orderFileByApiDtos.stream()
                                    .filter(orderFileByApiDto -> StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderFileByApiDto.getTrackId()))
                                    .collect(Collectors.toList());
                            if (CollUtil.isNotEmpty(apiBySendLetters)) {
                                List<List<OrderFileByApiDto>> partition = ListUtil.partition(this.handlerExportBeforeForApiV2(apiBySendLetters, null), 5000);
                                for (int i = 0; i < partition.size(); i++) {
                                    ByteArrayOutputStream apiBos = new ByteArrayOutputStream();
                                    List<OrderFileByApiDto> temp = BeanCopierUtils.listCopyMapper(
                                            partition.get(i),
                                            OrderFileByApiDto.class,
                                            OrderFileByApiDto.class
                                    );
                                    CsvUtils.exportCsv(
                                            csvParam,
                                            OrderFileByApiDto.class,
                                            temp,
                                            apiBos
                                    );
                                    String itemFileName;
                                    long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByApiDto::getOutboundNo)).count();
                                    int size = partition.get(i).size();
                                    if (partition.size() > 1) {
                                        itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行-" + (i + 1) + ".csv";
                                    } else {
                                        itemFileName = fileNameTime + "三方倉-1個ネコ-API-" + num1 + "件-" + size + "行.csv";
                                    }
                                    exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), apiBos));
                                }
                            }
                        }
                    } else if (Objects.nonNull(storageId) && StaticDict.CM_Storage.MyselfStorage.getValue().equals(storageId)) {
                        //全都为自有仓库
                        //自有仓库按照原订单渠道导出
                        Map<Long, List<OutboundOldExportDto>> map = new HashMap<>(8);
                        List<OutboundOldExportDto> temp1 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        (Objects.nonNull(orderCrossMallDo.getStorageId())
                                         && StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        ) || (Objects.nonNull(orderCrossMallDo.getTrackId())
                                              && (StaticDict.Order_CM_Track.YamatoOne.getValue().equals(orderCrossMallDo.getTrackId())
                                                  || StaticDict.Order_CM_Track.YamatoMore.getValue().equals(orderCrossMallDo.getTrackId())
                                              ))
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp1)) {
                            map.put(StaticDict.Order_CM_Track.YamatoOne.getValue(), temp1);
                        }
                        List<OutboundOldExportDto> temp2 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        Objects.nonNull(orderCrossMallDo.getStorageId())
                                        && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        && Objects.nonNull(orderCrossMallDo.getTrackId())
                                        && StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(orderCrossMallDo.getTrackId())
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp2)) {
                            map.put(StaticDict.Order_CM_Track.YamatoZhai.getValue(), temp2);
                        }
                        List<OutboundOldExportDto> temp3 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        Objects.nonNull(orderCrossMallDo.getStorageId())
                                        && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        && Objects.nonNull(orderCrossMallDo.getTrackId())
                                        && StaticDict.Order_CM_Track.Sagawa.getValue().equals(orderCrossMallDo.getTrackId())
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp3)) {
                            map.put(StaticDict.Order_CM_Track.Sagawa.getValue(), temp3);
                        }
                        List<OutboundOldExportDto> temp4 = storageDataInfo.stream()
                                .filter(orderCrossMallDo ->
                                        Objects.nonNull(orderCrossMallDo.getStorageId())
                                        && !StaticDict.CM_Storage.ThirdStorage.getValue().equals(orderCrossMallDo.getStorageId())
                                        && Objects.nonNull(orderCrossMallDo.getTrackId())
                                        && StaticDict.Order_CM_Track.KKKK.getValue().equals(orderCrossMallDo.getTrackId())
                                )
                                .collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(temp4)) {
                            map.put(StaticDict.Order_CM_Track.KKKK.getValue(), temp4);
                        }
                        map.forEach((trackId, value) -> {
                            try {
                                if (StaticDict.Order_CM_Track.YamatoZhai.getValue().equals(trackId)) {
                                    //黑猫宅急便每1000条数据一个文件
                                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                            this.handlerExportBeforeForBlackCatV2(value, OrderFileByBlackCatDto::getProductCode1),
                                            1000
                                    );
                                    //同一管理番号同一个文件
//                                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                                    for (int i = 0; i < partition.size(); i++) {
                                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                                partition.get(i),
                                                OrderFileByBlackCatDto.class,
                                                OrderFileByBlackCatDto.class
                                        );
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ExcelUtils.exportExcel(
                                                temp,
                                                OrderFileByBlackCatDto.class,
                                                excelParam,
                                                outputStream
                                        );
                                        String itemFileName;
                                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                        int size = partition.get(i).size();
                                        if (partition.size() > 1) {
                                            itemFileName = fileNameTime + "本地仓-佐川急便订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                        } else {
                                            itemFileName = fileNameTime + "本地仓-佐川急便订单-" + num1 + "件-" + size + "行.xlsx";
                                        }
                                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                                    }
                                } else if (StaticDict.Order_CM_Track.Sagawa.getValue().equals(trackId)) {
                                    //佐川急便
                                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                                    ExcelUtils.exportExcel(
                                            this.handlerExportBeforeForSagawaV2(value, OrderFileBySagawaDto::getProductCode1),
                                            OrderFileBySagawaDto.class,
                                            excelParam,
                                            bos
                                    );
                                    long num1 = value.stream().filter(distinctByKey(OutboundOldExportDto::getOutboundNo)).count();
                                    int size = value.size();
                                    exportZipDtoList.add(
                                            new ExportZipDto(
                                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.xlsx"),
                                                    bos
                                            )
                                    );
                                    ByteArrayOutputStream csvBos = new ByteArrayOutputStream();
                                    CsvUtils.exportCsv(
                                            csvParamWithoutHead,
                                            OrderFileBySagawaDto.class,
                                            this.handlerExportBeforeForSagawaV2(value, OrderFileBySagawaDto::getProductCode1),
                                            csvBos
                                    );
                                    exportZipDtoList.add(
                                            new ExportZipDto(
                                                    new ZipEntry(fileNameTime + "本地仓-佐川急便-" + num1 + "件-" + size + "行.csv"),
                                                    csvBos
                                            )
                                    );
                                } else if (StaticDict.Order_CM_Track.KKKK.getValue().equals(trackId)) {
                                    //コンパクト
                                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                            this.handlerExportBeforeForBlackCatV2(value, OrderFileByBlackCatDto::getProductCode1),
                                            1000
                                    );
                                    //同一管理番号同一个文件
//                                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                                    for (int i = 0; i < partition.size(); i++) {
                                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                                partition.get(i),
                                                OrderFileByBlackCatDto.class,
                                                OrderFileByBlackCatDto.class
                                        );
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ExcelUtils.exportExcel(
                                                temp,
                                                OrderFileByBlackCatDto.class,
                                                excelParam,
                                                outputStream
                                        );
                                        String itemFileName;
                                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                        int size = partition.get(i).size();
                                        if (partition.size() > 1) {
                                            itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                        } else {
                                            itemFileName = fileNameTime + "本地仓-コンパクト订单-" + num1 + "件-" + size + "行.xlsx";
                                        }
                                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                                    }
                                } else {
                                    //投函
                                    List<List<OrderFileByBlackCatDto>> partition = ListUtil.partition(
                                            this.handlerExportBeforeForBlackCatV2(value, OrderFileByBlackCatDto::getProductCode1),
                                            1000
                                    );
                                    //同一管理番号同一个文件
//                                partition = sameOrderNumberSameList(partition, OrderFileByBlackCatDto::getOutboundNo, 1000);
                                    for (int i = 0; i < partition.size(); i++) {
                                        List<OrderFileByBlackCatDto> temp = BeanCopierUtils.listCopyMapper(
                                                partition.get(i),
                                                OrderFileByBlackCatDto.class,
                                                OrderFileByBlackCatDto.class
                                        );
                                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                                        ExcelUtils.exportExcel(
                                                temp,
                                                OrderFileByBlackCatDto.class,
                                                excelParam,
                                                outputStream
                                        );
                                        String itemFileName;
                                        long num1 = partition.get(i).stream().filter(distinctByKey(OrderFileByBlackCatDto::getOutboundNo)).count();
                                        int size = partition.get(i).size();
                                        if (partition.size() > 1) {
                                            itemFileName = fileNameTime + "本地仓-佐川投函订单-" + num1 + "件-" + size + "行-" + (i + 1) + ".xlsx";
                                        } else {
                                            itemFileName = fileNameTime + "本地仓-佐川投函订单-" + num1 + "件-" + size + "行.xlsx";
                                        }
                                        exportZipDtoList.add(new ExportZipDto(new ZipEntry(itemFileName), outputStream));
                                    }
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });
                    }
                }
            }
        }
        response.setHeader("Content-Type", "application/x-zip-compressed");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setCharacterEncoding("Shift-JIS");
        for (ExportZipDto exportZipDto : exportZipDtoList) {
            //编写新的zip条目，并将流定位到条目数据的开头
            zos.putNextEntry(exportZipDto.getZipEntry());
            //写入zos
            exportZipDto.getBos().writeTo(zos);
            zos.closeEntry();
        }
        zos.finish();
        zos.close();
    }

    /**
     * 相同订单放于同一个列表
     *
     * @param dataPartition       数据
     * @param getOrderNumberField 判断相同订单的字段
     * @param listSize            列表大小
     * @param <E>                 元素类型
     */
    private <E> List<List<E>> sameOrderNumberSameList(List<List<E>> dataPartition, Function<E, String> getOrderNumberField, int listSize) {
        List<List<E>> dataList = new ArrayList<>(dataPartition.size());
        Map<Integer, List<E>> addMap = new HashMap<>(8);
        Map<Integer, List<E>> removeMap = new HashMap<>(8);
        if (dataPartition.size() > 1) {
            for (int i = 0; i < dataPartition.size() - 1; i++) {
                int j = i + 1;
                String orderNumber1 = getOrderNumberField.apply(dataPartition.get(i).get(listSize - 1));
                String orderNumber2 = getOrderNumberField.apply(dataPartition.get(j).get(0));
                if (this.isSameOrderNumber(orderNumber1, orderNumber2)) {
//                    dataPartition.get(i).addAll(dataPartition.get(j).stream()
//                            .filter(d -> this.isSameOrderNumber(orderNumber2, getOrderNumberField.apply(d)))
//                            .collect(Collectors.toList()));
//                    dataPartition.get(j).removeIf(d -> this.isSameOrderNumber(orderNumber2, getOrderNumberField.apply(d)));
                    List<E> temp = dataPartition.get(j).stream()
                            .filter(d -> this.isSameOrderNumber(orderNumber2, getOrderNumberField.apply(d)))
                            .collect(Collectors.toList());
                    addMap.computeIfAbsent(i, k -> new ArrayList<>()).addAll(temp);
                    removeMap.computeIfAbsent(j, k -> new ArrayList<>()).addAll(temp);
                }
            }
            for (int i = 0; i < dataPartition.size(); i++) {
                List<E> temp = new ArrayList<>(dataPartition.get(i));
                temp.addAll(addMap.getOrDefault(i, new ArrayList<>()));
                temp.removeAll(removeMap.getOrDefault(i, new ArrayList<>()));
                if (CollUtil.isNotEmpty(temp)) {
                    dataList.add(temp);
                }
            }
        } else {
            return dataPartition;
        }
        return dataList;
//        return dataPartition;
    }

    /**
     * 提取判断订单号是否相同的逻辑  订单号相同以-拼接序号 如：abc-1 abc-2
     */
    private boolean isSameOrderNumber(String orderNumber1, String orderNumber2) {
        return orderNumber1.equals(orderNumber2)
               || orderNumber1.substring(0, orderNumber1.lastIndexOf("-") == -1
                        ? orderNumber1.length() : orderNumber1.lastIndexOf("-"))
                       .equals(orderNumber2.substring(0, orderNumber2.lastIndexOf("-") == -1
                               ? orderNumber2.length() : orderNumber2.lastIndexOf("-")));
    }

    /**
     * 导出第三方仓库连接api的文件 前置处理(目前宅急便是固定的666，投函1001)
     */
    private List<OrderFileByApiDto> handlerExportBeforeForApi(List<OrderFileByApiDto> apiDtoList, Long trackIdByExport) {
        apiDtoList.forEach(
                apiDto -> {
                    Long trackId = ObjectUtil.isNotNull(trackIdByExport) ? trackIdByExport : apiDto.getTrackId();
                    switch (StaticDict.Order_CM_Track.getTrack(trackId)) {
                        case YamatoZhai:
                            apiDto.setDeliveryName("666");
                            break;
                        case YamatoOne:
                            apiDto.setDeliveryName("1001");
                            break;
                        default:
                            apiDto.setDeliveryName("");
                    }
                });
        return apiDtoList;
    }

    private List<OrderFileByApiDto> handlerExportBeforeForApiV2(List<OrderFileByApiDto> apiDtoList, Long trackIdByExport) {
        apiDtoList.forEach(
                apiDto -> {
                    Long trackId = ObjectUtil.isNotNull(trackIdByExport) ? trackIdByExport : apiDto.getTrackId();
                    switch (StaticDict.Order_CM_Track.getTrack(trackId)) {
                        case YamatoZhai:
                            apiDto.setDeliveryName("666");
                            break;
                        case YamatoOne:
                            apiDto.setDeliveryName("1001");
                            break;
                        default:
                            apiDto.setDeliveryName("");
                    }
                });
        return apiDtoList;
    }

    /**
     * 第三方仓库订单数据导出前置处理
     */
    private List<OrderFileByThirdPartyDto> handlerExportBeforeForThirdParty(List<OrderFileByThirdPartyDto> thirdPartyDtoList, Long trackIdByExport) {
        if (CollUtil.isEmpty(thirdPartyDtoList)) {
            return thirdPartyDtoList;
        }
        List<Long> outIds = thirdPartyDtoList.stream().map(OrderFileByThirdPartyDto::getId).collect(Collectors.toList());
        //获取投函分包裹信息
        Map<Long, List<OrderOutboundPackageDo>> outIdMatchPackages = outboundPackageService.lambdaQuery()
                .in(OrderOutboundPackageDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDo::getOutboundId));
        Map<Long, List<OrderOutboundPackageDetailDo>> packIdMatchSkuInfo = outboundPackageDetailService.lambdaQuery()
                .in(OrderOutboundPackageDetailDo::getPackageId, outIdMatchPackages.values().stream().flatMap(List::stream).map(OrderOutboundPackageDo::getId).collect(Collectors.toSet()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDetailDo::getPackageId));
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        List<OrderFileByThirdPartyDto> addList = new ArrayList<>();
        for (OrderFileByThirdPartyDto thirdPartyDto : thirdPartyDtoList) {
            //强制修改渠道
            if (ObjectUtil.isNotNull(trackIdByExport)) {
                thirdPartyDto.setTrackId(trackIdByExport);
                if (trackIdByExport.equals(100L) || trackIdByExport.equals(200L)) {
                    thirdPartyDto.setDeliveryName("ネコポス");
                } else {
                    thirdPartyDto.setDeliveryName(thirdPartyDto.getTrackId().equals(300L) ? "宅急便" : "佐川急便");
                }
            }
            thirdPartyDto.setOrderTime(new Date());
            //根据邮编获取都道府县
            if (StrUtil.isBlank(thirdPartyDto.getProvinceName())) {
                JpRegionDo regionDo = jpRegionService.getRegionDoByPostCode(thirdPartyDto.getPostCode());
                if (regionDo != null) {
                    thirdPartyDto.setProvinceName(regionDo.getName());
                }
            }
            //去除地址中存在的逗号、引号、回车、空格
            thirdPartyDto.setProvinceName(replaceStr(thirdPartyDto.getProvinceName()) + (StrUtil.isNotBlank(thirdPartyDto.getCityName()) ? replaceStr(thirdPartyDto.getCityName()) : ""));
            thirdPartyDto.setAddress1(replaceStr(thirdPartyDto.getAddress1()));
            thirdPartyDto.setAddress2(replaceStr(thirdPartyDto.getAddress2()));
            thirdPartyDto.setAddress3(replaceStr(thirdPartyDto.getAddress3()));
            //电话号码为空置为0
            if (StrUtil.isBlank(thirdPartyDto.getPhone())) {
                thirdPartyDto.setPhone("0");
            } else {
                thirdPartyDto.setPhone(thirdPartyDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (thirdPartyDto.getTrackId().equals(100L) || thirdPartyDto.getTrackId().equals(200L)) {
                List<OrderOutboundPackageDo> packageDoListByOrderId = outIdMatchPackages.get(thirdPartyDto.getId());
                if (CollUtil.isEmpty(packageDoListByOrderId)) {
                    continue;
                }
                boolean multi_package = packageDoListByOrderId.stream()
                                                .mapToInt(OrderOutboundPackageDo::getSerialNumber)
                                                .max().getAsInt() > 1;
                for (OrderOutboundPackageDo packageDo : packageDoListByOrderId) {
                    List<OrderOutboundPackageDetailDo> packageDetailDoList = packIdMatchSkuInfo.get(packageDo.getId());
                    if (CollUtil.isEmpty(packageDetailDoList)) {
                        continue;
                    }
                    packageDetailDoList = new ArrayList<>(
                            packageDetailDoList.stream().collect(Collectors.toMap(OrderOutboundPackageDetailDo::getProductId, i -> i, (o1, o2) -> {
                                o1.setQty(o1.getQty() + o2.getQty());
                                return o1;
                            })).values()
                    );
                    String outboundNo = thirdPartyDto.getPlatformOrderNo() + " " +
                                        (multi_package ? thirdPartyDto.getOutboundNo() + "-" + packageDo.getSerialNumber() : thirdPartyDto.getOutboundNo());
                    for (OrderOutboundPackageDetailDo packageDetailDo : packageDetailDoList) {
//                        OrderFileByThirdPartyDto dto = new OrderFileByThirdPartyDto();
//                        BeanUtils.copyProperties(thirdPartyDto, dto);
                        OrderFileByThirdPartyDto dto = BeanConvert.INSTANCE.copyOrderFileByThirdPartyDto(thirdPartyDto);
                        dto.setItemCode(packageDetailDo.getSku());
                        dto.setAmount(packageDetailDo.getQty());
                        dto.setOutboundNo(outboundNo);
                        // 店铺编码获取
                        if (Objects.nonNull(thirdPartyDto.getSalesPlatform())) {
                            dto.setPlatformOrderNo(SalesPlatformEnum.getNameByVal(thirdPartyDto.getSalesPlatform()) + " " + thirdPartyDto.getPlatformOrderNo());
                        }
                        dto.setDeliveryName("ネコポス");
                        //投函清空配送日信息
                        dto.setDeliveryDate("");
                        dto.setDeliveryTimeName("");
                        addList.add(dto);
                    }
                }
            } else {
                //处理急便的订单
                thirdPartyDto.setDeliveryName(thirdPartyDto.getTrackId().equals(300L) ? "宅急便" : "佐川急便");
                //相同订单的相同SKU合并到同一个item展示
                List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(thirdPartyDto.getId());
                if (CollUtil.isNotEmpty(outboundProductDoList)) {
                    outboundProductDoList = new ArrayList<>(outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                        o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                        o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                        return o1;
                    })).values());
                    for (OrderOutboundProductDo outboundProductDo : outboundProductDoList) {
//                        OrderFileByThirdPartyDto dto = new OrderFileByThirdPartyDto();
//                        BeanUtils.copyProperties(thirdPartyDto, dto);
                        OrderFileByThirdPartyDto dto = BeanConvert.INSTANCE.copyOrderFileByThirdPartyDto(thirdPartyDto);
                        dto.setOutboundNo(thirdPartyDto.getPlatformOrderNo() + " " + thirdPartyDto.getOutboundNo());
                        if (Objects.nonNull(thirdPartyDto.getSalesPlatform())) {
                            //店铺编码获取
                            dto.setPlatformOrderNo(SalesPlatformEnum.getNameByVal(thirdPartyDto.getSalesPlatform()) + " " + thirdPartyDto.getPlatformOrderNo());
                        }
                        dto.setItemCode(productIdMatchDo.get(outboundProductDo.getProductId()).getSku());
                        dto.setAmount(outboundProductDo.getOutboundQty().equals(0) ? outboundProductDo.getForecastQty() : outboundProductDo.getOutboundQty());
                        dto.setDeliveryDate(thirdPartyDto.getDeliveryDate());
                        if (StrUtil.isNotBlank(dto.getDeliveryDate())) {
                            dto.setDeliveryDate(dto.getDeliveryDate().replaceAll("-", "/"));
                            /*if (dto.getDeliveryDate().matches(regex)) {
                                //配送日在今天之前，将日期改为明天
                                if (DateUtil.parse(dto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                                    dto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                                }
                            }
                            if (dto.getDeliveryDate().matches(regex1)) {
                                //配送日在今天之前，将日期改为明天
                                if (DateUtil.parse(dto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                                    dto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                                }
                                dto.setDeliveryDate(dto.getDeliveryDate().replaceAll("-", "/"));
                            }*/
                        }
                        if (StrUtil.isNotBlank(thirdPartyDto.getDeliveryTimeName())) {
                            dto.setDeliveryTimeName(thirdPartyDto.getDeliveryTimeName().replace("-", ""));
                        }
                        addList.add(dto);
                    }
                }
            }
        }
        //替换投函的订单记录
        List<Long> temp = addList.stream().map(OrderFileByThirdPartyDto::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(temp)) {
            thirdPartyDtoList = thirdPartyDtoList.stream().filter(i -> !temp.contains(i.getId())).collect(Collectors.toList());
            thirdPartyDtoList.addAll(addList);
        }
        return thirdPartyDtoList.stream().sorted(Comparator.comparing(OrderFileByThirdPartyDto::getOutboundNo, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    private List<OrderFileByThirdPartyDto> handlerExportBeforeForThirdPartyV2(List<OrderFileByThirdPartyDto> thirdPartyDtoList, Long trackIdByExport) {
        if (CollUtil.isEmpty(thirdPartyDtoList)) {
            return thirdPartyDtoList;
        }
        List<Long> outIds = thirdPartyDtoList.stream().map(OrderFileByThirdPartyDto::getId).collect(Collectors.toList());
        //获取投函分包裹信息
        Map<Long, List<OrderOutboundPackageDo>> outIdMatchPackages = outboundPackageService.lambdaQuery()
                .in(OrderOutboundPackageDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDo::getOutboundId));
        Map<Long, List<OrderOutboundPackageDetailDo>> packIdMatchSkuInfo = outboundPackageDetailService.lambdaQuery()
                .in(OrderOutboundPackageDetailDo::getPackageId, outIdMatchPackages.values().stream().flatMap(List::stream).map(OrderOutboundPackageDo::getId).collect(Collectors.toSet()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDetailDo::getPackageId));
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        List<OrderFileByThirdPartyDto> addList = new ArrayList<>();
        for (OrderFileByThirdPartyDto thirdPartyDto : thirdPartyDtoList) {//强制修改渠道
            if (ObjectUtil.isNotNull(trackIdByExport)) {
                thirdPartyDto.setTrackId(trackIdByExport);
                if (trackIdByExport.equals(100L) || trackIdByExport.equals(200L)) {
                    thirdPartyDto.setDeliveryName("ネコポス");
                } else {
                    thirdPartyDto.setDeliveryName(thirdPartyDto.getTrackId().equals(300L) ? "宅急便" : "佐川急便");
                }
            }
            thirdPartyDto.setOrderTime(new Date());
            //根据邮编获取都道府县
            if (StrUtil.isBlank(thirdPartyDto.getProvinceName())) {
                JpRegionDo regionDo = jpRegionService.getRegionDoByPostCode(thirdPartyDto.getPostCode());
                if (regionDo != null) {
                    thirdPartyDto.setProvinceName(regionDo.getName());
                }
            }
            //去除地址中存在的逗号、引号、回车、空格
            thirdPartyDto.setProvinceName(replaceStr(thirdPartyDto.getProvinceName()) + (StrUtil.isNotBlank(thirdPartyDto.getCityName()) ? replaceStr(thirdPartyDto.getCityName()) : ""));
            thirdPartyDto.setAddress1(replaceStr(thirdPartyDto.getAddress1()));
            thirdPartyDto.setAddress2(replaceStr(thirdPartyDto.getAddress2()));
            thirdPartyDto.setAddress3(replaceStr(thirdPartyDto.getAddress3()));
            //电话号码为空置为0
            if (StrUtil.isBlank(thirdPartyDto.getPhone())) {
                thirdPartyDto.setPhone("0");
            } else {
                thirdPartyDto.setPhone(thirdPartyDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (thirdPartyDto.getTrackId().equals(100L) || thirdPartyDto.getTrackId().equals(200L)) {
                List<OrderOutboundPackageDo> packageDoListByOrderId = outIdMatchPackages.get(thirdPartyDto.getId());
                if (CollUtil.isEmpty(packageDoListByOrderId)) {
                    continue;
                }
                boolean multi_package = packageDoListByOrderId.stream()
                                                .mapToInt(OrderOutboundPackageDo::getSerialNumber)
                                                .max().getAsInt() > 1;
                for (OrderOutboundPackageDo packageDo : packageDoListByOrderId) {
                    List<OrderOutboundPackageDetailDo> packageDetailDoList = packIdMatchSkuInfo.get(packageDo.getId());
                    if (CollUtil.isEmpty(packageDetailDoList)) {
                        continue;
                    }
                    packageDetailDoList = new ArrayList<>(
                            packageDetailDoList.stream().collect(Collectors.toMap(OrderOutboundPackageDetailDo::getProductId, i -> i, (o1, o2) -> {
                                o1.setQty(o1.getQty() + o2.getQty());
                                return o1;
                            })).values()
                    );
                    String outboundNo = thirdPartyDto.getPlatformOrderNo() + " " +
                                        (multi_package ? thirdPartyDto.getOutboundNo() + "-" + packageDo.getSerialNumber() : thirdPartyDto.getOutboundNo());
                    for (OrderOutboundPackageDetailDo packageDetailDo : packageDetailDoList) {
//                        OrderFileByThirdPartyDto dto = new OrderFileByThirdPartyDto();
//                        BeanUtils.copyProperties(thirdPartyDto, dto);
                        OrderFileByThirdPartyDto dto = BeanConvert.INSTANCE.copyOrderFileByThirdPartyDto(thirdPartyDto);
                        dto.setItemCode(packageDetailDo.getSku());
                        dto.setAmount(packageDetailDo.getQty());
                        dto.setOutboundNo(outboundNo);
                        // 店铺编码获取
                        if (Objects.nonNull(thirdPartyDto.getSalesPlatform())) {
                            dto.setPlatformOrderNo(SalesPlatformEnum.getNameByVal(thirdPartyDto.getSalesPlatform()) + " " + thirdPartyDto.getPlatformOrderNo());
                        }
                        dto.setDeliveryName("ネコポス");
                        //投函清空配送日信息
                        dto.setDeliveryDate("");
                        dto.setDeliveryTimeName("");
                        addList.add(dto);
                    }
                }
            } else {
                //处理急便的订单
                thirdPartyDto.setDeliveryName(thirdPartyDto.getTrackId().equals(300L) ? "宅急便" : "佐川急便");
                //相同订单的相同SKU合并到同一个item展示
                List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(thirdPartyDto.getId());
                if (CollUtil.isNotEmpty(outboundProductDoList)) {
                    //合并相同SKU
                    outboundProductDoList = new ArrayList<>(outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                        o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                        o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                        return o1;
                    })).values());
                    for (OrderOutboundProductDo outboundProductDo : outboundProductDoList) {
//                        OrderFileByThirdPartyDto dto = new OrderFileByThirdPartyDto();
//                        BeanUtils.copyProperties(thirdPartyDto, dto);
                        OrderFileByThirdPartyDto dto = BeanConvert.INSTANCE.copyOrderFileByThirdPartyDto(thirdPartyDto);
                        dto.setOutboundNo(thirdPartyDto.getPlatformOrderNo() + " " + thirdPartyDto.getOutboundNo());
                        // 店铺编码获取
                        if (Objects.nonNull(thirdPartyDto.getSalesPlatform())) {
                            dto.setPlatformOrderNo(SalesPlatformEnum.getNameByVal(thirdPartyDto.getSalesPlatform()) + " " + thirdPartyDto.getPlatformOrderNo());
                        }
                        dto.setItemCode(productIdMatchDo.get(outboundProductDo.getProductId()).getSku());
                        dto.setAmount(outboundProductDo.getOutboundQty().equals(0) ? outboundProductDo.getForecastQty() : outboundProductDo.getOutboundQty());
                        dto.setDeliveryDate(thirdPartyDto.getDeliveryDate());
                        if (StrUtil.isNotBlank(dto.getDeliveryDate())) {
                            dto.setDeliveryDate(dto.getDeliveryDate().replaceAll("-", "/"));
                            /*if (dto.getDeliveryDate().matches(regex)) {
                                //配送日在今天之前，将日期改为明天
                                if (DateUtil.parse(dto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                                    dto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                                }
                            }
                            if (dto.getDeliveryDate().matches(regex1)) {
                                //配送日在今天之前，将日期改为明天
                                if (DateUtil.parse(dto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                                    dto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                                }
                                dto.setDeliveryDate(dto.getDeliveryDate().replaceAll("-", "/"));
                            }*/
                        }
                        if (StrUtil.isNotBlank(thirdPartyDto.getDeliveryTimeName())) {
                            dto.setDeliveryTimeName(thirdPartyDto.getDeliveryTimeName().replace("-", ""));
                        }
                        addList.add(dto);
                    }
                }
            }
        }
        //替换投函的订单记录
        List<Long> temp = addList.stream().map(OrderFileByThirdPartyDto::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(temp)) {
            thirdPartyDtoList = thirdPartyDtoList.stream().filter(i -> !temp.contains(i.getId())).collect(Collectors.toList());
            thirdPartyDtoList.addAll(addList);
        }
        return thirdPartyDtoList.stream().sorted(Comparator.comparing(OrderFileByThirdPartyDto::getOutboundNo, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    /**
     * 佐川宅急便订单导出数据前置处理
     */
    private List<OrderFileBySagawaDto> handlerExportBeforeForSagawa(List<OutboundOldExportDto> dtoList, Function<OrderFileBySagawaDto, String> orderField) {
        if (CollUtil.isEmpty(dtoList)) {
            return new ArrayList<>();
        }
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, dtoList.stream().map(OutboundOldExportDto::getId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        Set<Long> productCategoryIdSet = productIdMatchDo.values().stream().map(ProductDo::getCategoryId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> categoryIdMatchName = new HashMap<>();
        if (CollUtil.isNotEmpty(productCategoryIdSet)) {
            categoryIdMatchName = productCategoryService.lambdaQuery()
                    .in(ProductCategoryDo::getId, productCategoryIdSet)
                    .list().stream().collect(Collectors.toMap(ProductCategoryDo::getId, i -> !i.getFullPathName().contains("\\") ? i.getFullPathName() : i.getFullPathName().substring(0, i.getFullPathName().indexOf("\\"))));
        }
        ArrayList<OrderFileBySagawaDto> sagawaDtoList = new ArrayList<>(5000);
        for (OutboundOldExportDto dto : dtoList) {
//            OrderFileBySagawaDto sagawaDto = new OrderFileBySagawaDto();
//            BeanUtils.copyProperties(dto, sagawaDto);
            OrderFileBySagawaDto sagawaDto = BeanConvert.INSTANCE.outboundOldExportDtoToOrderFileBySagawaDto(dto);
            //管理番号由 注文番号 + 空格 + 管理番号 组成
            sagawaDto.setOutboundNo(dto.getPlatformOrderNo() + " " + dto.getOutboundNo());
            String address = (StrUtil.isNotBlank(dto.getProvinceName()) ? dto.getProvinceName() : "")
                             + (StrUtil.isNotBlank(dto.getCityName()) ? dto.getCityName() : "")
                             + (StrUtil.isNotBlank(dto.getAddress1()) ? dto.getAddress1() : "")
                             + (StrUtil.isNotBlank(dto.getAddress2()) ? dto.getAddress2() : "");
            //去除地址中存在的逗号、引号、回车、空格
            address = replaceStr(address);
            if (address.length() <= 15) {
                sagawaDto.setAddress1(address);
            } else if (address.length() <= 30) {
                sagawaDto.setAddress1(address.substring(0, 15));
                sagawaDto.setAddress2(address.substring(15));
            } else {
                sagawaDto.setAddress1(address.substring(0, 15));
                sagawaDto.setAddress2(address.substring(15, 30));
                sagawaDto.setAddress3(address.substring(30));
            }
            //电话号码为空置为0
            if (StrUtil.isBlank(sagawaDto.getPhone())) {
                sagawaDto.setPhone("0");
            } else {
                sagawaDto.setPhone(sagawaDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (StrUtil.isNotBlank(sagawaDto.getDeliveryDate())) {
                sagawaDto.setDeliveryDate(sagawaDto.getDeliveryDate().replaceAll("-", "/"));
                /*if (sagawaDto.getDeliveryDate().matches(regex)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(sagawaDto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                        sagawaDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                }
                if (sagawaDto.getDeliveryDate().matches(regex1)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(sagawaDto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                        sagawaDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                    sagawaDto.setDeliveryDate(sagawaDto.getDeliveryDate().replaceAll("-", "/"));

                }*/
            }
            //时间带需要变换
            if (StrUtil.isNotBlank(dto.getDeliveryTimeName())) {
                String timeBand;
                try {
                    int length = dto.getDeliveryTimeName().length();
                    if (length > 8) {
                        timeBand = dto.getDeliveryTimeName().substring(0, 2) + dto.getDeliveryTimeName().substring(6, 8);
                    } else if (dto.getDeliveryTimeName().contains("午前中")) {
                        timeBand = "0812";
                    } else if (dto.getDeliveryTimeName().contains("指定なし")) {
                        timeBand = "";
                    } else if (length == 4) {
                        timeBand = dto.getDeliveryTimeName();
                    } else {
                        throw new Exception();
                    }
                } catch (Exception e) {
                    timeBand = dto.getDeliveryTimeName().replace("-", "");
                }
                sagawaDto.setDeliveryTimeName(timeBand);
            }
            List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(dto.getId());
            if (CollUtil.isEmpty(outboundProductDoList)) {
                continue;
            }
            //合并相同SKU
            outboundProductDoList = new ArrayList<>(outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                return o1;
            })).values());
            //品目 多种品类就是杂货  商品没有品目置空
            //种类数量
            Map<Long, String> finalCategoryIdMatchName = categoryIdMatchName;
            Set<String> proTypeList = outboundProductDoList.stream()
                    .map(i -> productIdMatchDo.get(i.getProductId()).getSku().startsWith("h1-") ? "スーツケース" : finalCategoryIdMatchName.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                    .filter(StrUtil::isNotBlank)
                    .collect(Collectors.toSet());
            if (proTypeList.size() > 1) {
                sagawaDto.setItemName("雑貨 " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
            } else {
                String type = "未分類";
                if (proTypeList.size() > 0) {
                    type = proTypeList.iterator().next();
                }
                sagawaDto.setItemName(type + " " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
            }
            // sku优先级：简体sku -> productSku
//            sagawaDto.setProductCode1(
//                    outboundProductDoList.stream()
//                            .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName()) + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? " * " + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
//                            ).sorted().collect(Collectors.joining(" ・ "))
//            );
            sagawaDto.setProductCode1(
                    outboundProductDoList.stream()
                            .map(i -> (productIdMatchDo.get(i.getProductId()).getSku()) + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? " * " + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
                            ).sorted().collect(Collectors.joining(" ・ "))
            );
            sagawaDto.setCode(outboundProductDoList.stream().anyMatch(i -> productIdMatchDo.get(i.getProductId()).getSku().startsWith("h1-")) ? "20" : "1");
            sagawaDtoList.add(sagawaDto);
        }
        return sagawaDtoList.stream().sorted(Comparator.comparing(orderField, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    private List<OrderFileBySagawaDto> handlerExportBeforeForSagawaV2(List<OutboundOldExportDto> dtoList, Function<OrderFileBySagawaDto, String> orderField) {
        if (CollUtil.isEmpty(dtoList)) {
            return Collections.emptyList();
        }
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, dtoList.stream().map(OutboundOldExportDto::getId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        Set<Long> productCategoryIdSet = productIdMatchDo.values().stream().map(ProductDo::getCategoryId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> categoryIdMatchName = new HashMap<>();
        if (CollUtil.isNotEmpty(productCategoryIdSet)) {
            categoryIdMatchName = productCategoryService.lambdaQuery()
                    .in(ProductCategoryDo::getId, productCategoryIdSet)
                    .list().stream().collect(Collectors.toMap(ProductCategoryDo::getId, i -> !i.getFullPathName().contains("\\") ? i.getFullPathName() : i.getFullPathName().substring(0, i.getFullPathName().indexOf("\\"))));
        }
        ArrayList<OrderFileBySagawaDto> sagawaDtoList = new ArrayList<>(5000);
        for (OutboundOldExportDto dto : dtoList) {
//            OrderFileBySagawaDto sagawaDto = new OrderFileBySagawaDto();
//            BeanUtils.copyProperties(dto, sagawaDto);
            OrderFileBySagawaDto sagawaDto = BeanConvert.INSTANCE.outboundOldExportDtoToOrderFileBySagawaDto(dto);
            //A列管理番号 B列注文番号
            sagawaDto.setOutboundNo(dto.getOutboundNo());
            sagawaDto.setB(dto.getPlatformOrderNo());
            String address = (StrUtil.isNotBlank(dto.getProvinceName()) ? dto.getProvinceName() : "")
                             + (StrUtil.isNotBlank(dto.getCityName()) ? dto.getCityName() : "")
                             + (StrUtil.isNotBlank(dto.getAddress1()) ? dto.getAddress1() : "")
                             + (StrUtil.isNotBlank(dto.getAddress2()) ? dto.getAddress2() : "");
            //去除地址中存在的逗号、引号、回车、空格
            address = replaceStr(address);
            if (address.length() <= 15) {
                sagawaDto.setAddress1(address);
            } else if (address.length() <= 30) {
                sagawaDto.setAddress1(address.substring(0, 15));
                sagawaDto.setAddress2(address.substring(15));
            } else {
                sagawaDto.setAddress1(address.substring(0, 15));
                sagawaDto.setAddress2(address.substring(15, 30));
                sagawaDto.setAddress3(address.substring(30));
            }
            //电话号码为空置为0
            if (StrUtil.isBlank(sagawaDto.getPhone())) {
                sagawaDto.setPhone("0");
            } else {
                sagawaDto.setPhone(sagawaDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (StrUtil.isNotBlank(sagawaDto.getDeliveryDate())) {
                sagawaDto.setDeliveryDate(sagawaDto.getDeliveryDate().replaceAll("-", "/"));
                /*if (sagawaDto.getDeliveryDate().matches(regex)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(sagawaDto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                        sagawaDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                }
                if (sagawaDto.getDeliveryDate().matches(regex1)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(sagawaDto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                        sagawaDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                    sagawaDto.setDeliveryDate(sagawaDto.getDeliveryDate().replaceAll("-", "/"));
                }*/
            }
            //时间带需要变换
            if (StrUtil.isNotBlank(dto.getDeliveryTimeName())) {
                String timeBand;
                try {
                    int length = dto.getDeliveryTimeName().length();
                    if (length > 8) {
                        timeBand = DeliveryTimeBand.getCodeByTimeBand(dto.getDeliveryTimeName().substring(0, 2) + dto.getDeliveryTimeName().substring(6, 8));
                    } else if (dto.getDeliveryTimeName().contains("午前中")) {
                        timeBand = "01";
                    } else if (dto.getDeliveryTimeName().contains("指定なし")) {
                        timeBand = "00";
                    } else if (length == 4) {
                        timeBand = DeliveryTimeBand.getCodeByTimeBand(dto.getDeliveryTimeName());
                    } else {
                        throw new Exception();
                    }
                } catch (Exception e) {
                    timeBand = dto.getDeliveryTimeName().replace("-", "");
                }
                sagawaDto.setDeliveryTimeName(timeBand);
            }
            List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(dto.getId());
            if (CollUtil.isEmpty(outboundProductDoList)) {
                continue;
            }
            //合并相同SKU
            outboundProductDoList = new ArrayList<>(outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                return o1;
            })).values());
            //品目 多种品类就是杂货  商品没有品目置空
            //种类数量
            Map<Long, String> finalCategoryIdMatchName = categoryIdMatchName;
            Set<String> proTypeList = outboundProductDoList.stream()
                    .map(i -> productIdMatchDo.get(i.getProductId()).getSku().startsWith("h1-") || productIdMatchDo.get(i.getProductId()).getSku().startsWith("h2-") ? "スーツケース" : finalCategoryIdMatchName.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                    .filter(StrUtil::isNotBlank)
                    .collect(Collectors.toSet());
            if (proTypeList.size() > 1) {
                sagawaDto.setItemName("雑貨 " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
            } else {
                String type = "未分類";
                if (proTypeList.size() > 0) {
                    type = proTypeList.iterator().next();
                }
                sagawaDto.setItemName(type + " " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
            }
            // sku优先级：简体sku -> productSku
//            sagawaDto.setProductCode1(
//                    outboundProductDoList.stream()
//                            .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName()) + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? " * " + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
//                            ).sorted().collect(Collectors.joining(" ・ "))
//            );
            sagawaDto.setProductCode1(
                    outboundProductDoList.stream()
                            .map(i -> (productIdMatchDo.get(i.getProductId()).getSku()) + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? " * " + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
                            ).sorted().collect(Collectors.joining(" ・ "))
            );
            sagawaDto.setCode(outboundProductDoList.stream().anyMatch(i -> productIdMatchDo.get(i.getProductId()).getSku().startsWith("h1-") || productIdMatchDo.get(i.getProductId()).getSku().startsWith("h2-")) ? "20" : "1");
            sagawaDtoList.add(sagawaDto);
        }
        return sagawaDtoList.stream().sorted(Comparator.comparing(orderField, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    /**
     * 黑猫订单导出数据前置处理
     */
    private List<OrderFileByBlackCatDto> handlerExportBeforeForBlackCat(List<OutboundOldExportDto> dtoList, Function<OrderFileByBlackCatDto, String> orderField) {
        if (CollUtil.isEmpty(dtoList)) {
            return Collections.emptyList();
        }
        List<Long> outIds = dtoList.stream().map(OutboundOldExportDto::getId).collect(Collectors.toList());
        //获取投函分包裹信息
        Map<Long, List<OrderOutboundPackageDo>> outIdMatchPackages = outboundPackageService.lambdaQuery()
                .in(OrderOutboundPackageDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDo::getOutboundId));
        Map<Long, List<OrderOutboundPackageDetailDo>> packIdMatchSkuInfo = outboundPackageDetailService.lambdaQuery()
                .in(OrderOutboundPackageDetailDo::getPackageId, outIdMatchPackages.values().stream().flatMap(List::stream).map(OrderOutboundPackageDo::getId).collect(Collectors.toSet()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDetailDo::getPackageId));
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        Set<Long> productCategoryIdSet = productIdMatchDo.values().stream().map(ProductDo::getCategoryId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> categoryIdMatchName = new HashMap<>();
        if (CollUtil.isNotEmpty(productCategoryIdSet)) {
            categoryIdMatchName = productCategoryService.lambdaQuery()
                    .in(ProductCategoryDo::getId, productCategoryIdSet)
                    .list().stream().collect(Collectors.toMap(ProductCategoryDo::getId, i -> !i.getFullPathName().contains("\\") ? i.getFullPathName() : i.getFullPathName().substring(0, i.getFullPathName().indexOf("\\"))));
        }
        Map<String, LocationCategoryDo> postalMatchLc = locationCategoryDao.selectList(
                Wrappers.<LocationCategoryDo>lambdaQuery()
                        .in(LocationCategoryDo::getPostcode, dtoList.stream()
                                .map(i -> StrUtil.isNotBlank(i.getPostCode()) ? extractDigits(i.getPostCode()) : "").collect(Collectors.toSet()))
        ).stream().collect(Collectors.toMap(LocationCategoryDo::getPostcode, val -> val, (o1, o2) -> o1));
        JpRegionDo jpRegionDo = jpRegionService.lambdaQuery().eq(JpRegionDo::getName, "沖縄県").last("limit 1").one();
        List<OrderFileByBlackCatDto> catDtoList = new ArrayList<>(5000);
        List<OrderFileByBlackCatDto> addList = new ArrayList<>(1000);
        List<OrderFileByBlackCatDto> finalCatDtoList = catDtoList;
        for (OutboundOldExportDto exportDto : dtoList) {
//            OrderFileByBlackCatDto catDto = new OrderFileByBlackCatDto();
//            BeanUtils.copyProperties(exportDto, catDto);
            OrderFileByBlackCatDto catDto = BeanConvert.INSTANCE.outboundOldExportDtoToOrderFileByBlackCatDto(exportDto);
            //管理番号由 注文番号 + 空格 + 管理番号 组成
            catDto.setOutboundNo(exportDto.getPlatformOrderNo() + " " + exportDto.getOutboundNo());
            String address = (StrUtil.isNotBlank(exportDto.getProvinceName()) ? exportDto.getProvinceName() : "")
                             + (StrUtil.isNotBlank(exportDto.getCityName()) ? exportDto.getCityName() : "")
                             + (StrUtil.isNotBlank(exportDto.getAddress1()) ? exportDto.getAddress1() : "")
                             + (StrUtil.isNotBlank(exportDto.getAddress2()) ? exportDto.getAddress2() : "");
            //去除地址中存在的逗号、引号、回车、空格
            address = replaceStr(address);
            if (address.length() <= 15) {
                catDto.setAddress1(address);
            } else if (address.length() <= 30) {
                catDto.setAddress1(address.substring(0, 15));
                catDto.setAddress2(address.substring(15));
            } else {
                catDto.setAddress1(address.substring(0, 15));
                catDto.setAddress2(address.substring(15, 30));
                catDto.setAddress3(address.substring(30));
            }
            //电话号码为空置为0
            if (StrUtil.isBlank(catDto.getPhone())) {
                catDto.setPhone("0");
            } else {
                catDto.setPhone(catDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (StrUtil.isNotBlank(catDto.getDeliveryDate())) {
                catDto.setDeliveryDate(catDto.getDeliveryDate().replaceAll("-", "/"));
                /*if (catDto.getDeliveryDate().matches(regex)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(catDto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                        catDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                }
                if (catDto.getDeliveryDate().matches(regex1)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(catDto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                        catDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                    catDto.setDeliveryDate(catDto.getDeliveryDate().replaceAll("-", "/"));
                }*/
            }
            //时间带需要变换
            if (StrUtil.isNotBlank(exportDto.getDeliveryTimeName())) {
                String timeBand;
                try {
                    int length = exportDto.getDeliveryTimeName().length();
                    if (length > 8) {
                        timeBand = exportDto.getDeliveryTimeName().substring(0, 2) + exportDto.getDeliveryTimeName().substring(6, 8);
                    } else if (exportDto.getDeliveryTimeName().contains("午前中")) {
                        timeBand = "0812";
                    } else if (exportDto.getDeliveryTimeName().contains("指定なし")) {
                        timeBand = "";
                    } else if (length == 4) {
                        timeBand = exportDto.getDeliveryTimeName();
                    } else {
                        throw new Exception();
                    }
                } catch (Exception e) {
                    timeBand = exportDto.getDeliveryTimeName().replace("-", "");
                }
                catDto.setDeliveryTimeName(timeBand);
            }

            //宅急便还是使用sku拼接的方式，投函多件分行处理
            if (exportDto.getTrackId().equals(300L) || exportDto.getTrackId().equals(500L)) {
                if (StrUtil.isNotBlank(exportDto.getPostCode())) {
                    LocationCategoryDo locationCategoryDo = postalMatchLc.get(extractDigits(exportDto.getPostCode()));
                    if (Objects.nonNull(locationCategoryDo)) {
                        catDto.setShipSectionName2(locationCategoryDo.getTypeCode());
                    }
                }
                List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(exportDto.getId());
                if (CollUtil.isEmpty(outboundProductDoList)) {
                    continue;
                }
                //合并相同SKU
                outboundProductDoList = new ArrayList<>(
                        outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                            o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                            o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                            return o1;
                        })).values()
                );
                //コンパクト  B 列， 固定值   是  8
                if (exportDto.getTrackId().equals(500L)) {
                    catDto.setB(String.valueOf(8));
                }
                //宅急便  B 列， 固定值   是  0
                if (exportDto.getTrackId().equals(300L)) {
                    catDto.setB(String.valueOf(0));
                }
                //品目 多种品类就是杂货  商品没有品目置空
                //种类数量
                Map<Long, String> finalCategoryIdMatchName = categoryIdMatchName;
                Set<String> proTypeList = outboundProductDoList.stream()
                        .map(i -> this.checkSuitcaseOrNot(productIdMatchDo.get(i.getProductId()).getSku()) ? "スーツケース" : finalCategoryIdMatchName.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                        .filter(StrUtil::isNotBlank)
                        .collect(Collectors.toSet());
                if (proTypeList.size() > 1) {
                    catDto.setItemName("雑貨 " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
                } else {
                    String type = "未分類";
                    if (proTypeList.size() > 0) {
                        type = proTypeList.iterator().next();
                    }
                    catDto.setItemName(type + " " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
                }
                //sku优先级：简体sku -> productSku
//                catDto.setProductCode1(
//                        outboundProductDoList.stream()
//                                .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                        + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? "*" + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
//                                ).sorted().collect(Collectors.joining("・"))
//                );
                catDto.setProductCode1(
                        outboundProductDoList.stream()
                                .map(i -> (productIdMatchDo.get(i.getProductId()).getSku())
                                          + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? "*" + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
                                ).sorted().collect(Collectors.joining("・"))
                );
                if (Objects.nonNull(jpRegionDo)) {
                    int postcode = Integer.parseInt(extractDigits(exportDto.getPostCode()));
                    //沖縄県特殊处理
                    if (jpRegionDo.getPostCodeStart() <= postcode && postcode <= jpRegionDo.getPostCodeEnd()) {
//                        if (proTypeList.contains("扇風機") || outboundProductDoList.stream()
//                                .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                ).anyMatch(this::startsWithE1ToE24)) {
//                            catDto.setItemName(catDto.getItemName() + " 【専用シール貼】");
//                        }
                        if (proTypeList.contains("扇風機") || outboundProductDoList.stream()
                                .map(i -> (productIdMatchDo.get(i.getProductId()).getSku())
                                ).anyMatch(this::startsWithE1ToE24)) {
                            catDto.setItemName(catDto.getItemName() + " 【専用シール貼】");
                        }
                    }
                }
                int skuStrLength = StrUtil.isBlank(catDto.getProductCode1()) ? 0 : catDto.getProductCode1().length();
                //宅急便数据sku拼接太长根据情况分割
                if (skuStrLength > 25 && skuStrLength < 50) {
                    String[] skuArr = catDto.getProductCode1().split("・");
                    skuArr = Arrays.stream(skuArr).sorted().toArray(String[]::new);
                    int splitLine = skuArr.length / 2;
                    catDto.setItemName(catDto.getItemName() + "・" + String.join("・", Arrays.copyOfRange(skuArr, 0, splitLine)));
                    catDto.setProductCode1(String.join("・", Arrays.copyOfRange(skuArr, splitLine, skuArr.length)));
                }
                catDto.setCode(outboundProductDoList.stream().anyMatch(i -> this.checkSuitcaseOrNot(productIdMatchDo.get(i.getProductId()).getSku())) ? "20" : "");
            } else {
                catDto.setB("A");
                if (StrUtil.isNotBlank(exportDto.getPostCode())) {
                    LocationCategoryDo locationCategoryDo = postalMatchLc.get(extractDigits(exportDto.getPostCode()));
                    if (Objects.nonNull(locationCategoryDo)) {
                        catDto.setShipSectionName2(locationCategoryDo.getCategory());
                    }
                }
                //投函多件
                List<OrderOutboundPackageDo> packageDoListByOrderId = outIdMatchPackages.get(exportDto.getId());
                if (CollUtil.isEmpty(packageDoListByOrderId)) {
                    continue;
                }
                boolean multi_package = packageDoListByOrderId.stream()
                                                .mapToInt(OrderOutboundPackageDo::getSerialNumber)
                                                .max().getAsInt() > 1;
                for (OrderOutboundPackageDo packageDo : packageDoListByOrderId) {
                    List<OrderOutboundPackageDetailDo> packageDetailDoList = packIdMatchSkuInfo.get(packageDo.getId());
                    if (CollUtil.isEmpty(packageDetailDoList)) {
                        continue;
                    }
                    packageDetailDoList = new ArrayList<>(
                            packageDetailDoList.stream().collect(Collectors.toMap(OrderOutboundPackageDetailDo::getProductId, i -> i, (o1, o2) -> {
                                o1.setQty(o1.getQty() + o2.getQty());
                                return o1;
                            })).values()
                    );
                    String outboundNo = multi_package
                            ? catDto.getOutboundNo() + "-" + packageDo.getSerialNumber()
                            : catDto.getOutboundNo();
//                    OrderFileByBlackCatDto dto = new OrderFileByBlackCatDto();
//                    BeanUtils.copyProperties(catDto, dto);
                    OrderFileByBlackCatDto dto = BeanConvert.INSTANCE.copyOrderFileByBlackCatDto(catDto);
                    dto.setOutboundNo(outboundNo);
                    //这个包裹品目
                    Map<Long, String> finalCategoryIdMatchName1 = categoryIdMatchName;
                    Set<String> packageProductType = packageDetailDoList.stream()
                            .map(i -> i.getSku().startsWith("h1-") ? "スーツケース" : finalCategoryIdMatchName1.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                            .filter(StrUtil::isNotBlank)
                            .collect(Collectors.toSet());
                    if (packageProductType.size() > 1) {
                        dto.setItemName("雑貨 " + packageDetailDoList.stream().map(OrderOutboundPackageDetailDo::getQty).reduce(0, Integer::sum));
                    } else {
                        String type = "未分類";
                        if (packageProductType.size() > 0) {
                            type = packageProductType.iterator().next();
                        }
                        dto.setItemName(type + " " + packageDetailDoList.stream().map(OrderOutboundPackageDetailDo::getQty).reduce(0, Integer::sum));
                    }
//                    String sku = packageDetailDoList.stream().map(
//                            i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? i.getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                    + (i.getQty() > 1 ? " * " + i.getQty() : "")
//                    ).sorted().collect(Collectors.joining(" ・ "));
                    String sku = packageDetailDoList.stream().map(
                            i -> (i.getSku()) + (i.getQty() > 1 ? " * " + i.getQty() : "")
                    ).sorted().collect(Collectors.joining(" ・ "));
                    dto.setProductCode1(sku);
                    //投函置空时间带
                    dto.setDeliveryTimeName("");
                    dto.setCode(packageDetailDoList.stream().anyMatch(i -> i.getSku().startsWith("h1-")) ? "20" : "");
                    addList.add(dto);
                }
            }
            finalCatDtoList.add(catDto);
        }
        List<Long> temp = addList.stream().map(OrderFileByBlackCatDto::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(temp)) {
            catDtoList = catDtoList.stream().filter(i -> !temp.contains(i.getId())).collect(Collectors.toList());
            catDtoList.addAll(addList);
        }
        return catDtoList.stream().sorted(Comparator.comparing(orderField, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    private List<OrderFileByBlackCatDto> handlerExportBeforeForBlackCatB2(List<OutboundOldExportDto> dtoList, Long trackIdByExport, Function<OrderFileByBlackCatDto, String> orderField) {
        if (CollUtil.isEmpty(dtoList)) {
            return Collections.emptyList();
        }
        List<Long> outIds = dtoList.stream().map(OutboundOldExportDto::getId).collect(Collectors.toList());
        //获取投函分包裹信息
        Map<Long, List<OrderOutboundPackageDo>> outIdMatchPackages = outboundPackageService.lambdaQuery()
                .in(OrderOutboundPackageDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDo::getOutboundId));
        Map<Long, List<OrderOutboundPackageDetailDo>> packIdMatchSkuInfo = outboundPackageDetailService.lambdaQuery()
                .in(OrderOutboundPackageDetailDo::getPackageId, outIdMatchPackages.values().stream().flatMap(List::stream).map(OrderOutboundPackageDo::getId).collect(Collectors.toSet()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDetailDo::getPackageId));
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        Set<Long> productCategoryIdSet = productIdMatchDo.values().stream().map(ProductDo::getCategoryId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> categoryIdMatchName = new HashMap<>();
        if (CollUtil.isNotEmpty(productCategoryIdSet)) {
            categoryIdMatchName = productCategoryService.lambdaQuery()
                    .in(ProductCategoryDo::getId, productCategoryIdSet)
                    .list().stream().collect(Collectors.toMap(ProductCategoryDo::getId, i -> !i.getFullPathName().contains("\\") ? i.getFullPathName() : i.getFullPathName().substring(0, i.getFullPathName().indexOf("\\"))));
        }
        Map<String, LocationCategoryDo> postalMatchLc = locationCategoryDao.selectList(
                Wrappers.<LocationCategoryDo>lambdaQuery()
                        .in(LocationCategoryDo::getPostcode, dtoList.stream().map(i -> StrUtil.isNotBlank(i.getPostCode()) ? extractDigits(i.getPostCode()) : "").collect(Collectors.toSet()))
        ).stream().collect(Collectors.toMap(LocationCategoryDo::getPostcode, val -> val, (o1, o2) -> o1));
        JpRegionDo jpRegionDo = jpRegionService.lambdaQuery().eq(JpRegionDo::getName, "沖縄県").last("limit 1").one();
        List<OrderFileByBlackCatDto> catDtoList = new ArrayList<>(5000);
        List<OrderFileByBlackCatDto> addList = new ArrayList<>(1000);
        List<OrderFileByBlackCatDto> finalCatDtoList = catDtoList;
        for (OutboundOldExportDto exportDto : dtoList) {
            //强制修改渠道
            if (ObjectUtil.isNotNull(trackIdByExport)) {
                exportDto.setTrackId(trackIdByExport);
            }
//            OrderFileByBlackCatDto catDto = new OrderFileByBlackCatDto();
//            BeanUtils.copyProperties(exportDto, catDto);
            OrderFileByBlackCatDto catDto = BeanConvert.INSTANCE.outboundOldExportDtoToOrderFileByBlackCatDto(exportDto);
            //管理番号由 注文番号 + 空格 + 管理番号 组成
            catDto.setOutboundNo(exportDto.getPlatformOrderNo() + " " + exportDto.getOutboundNo());
            String address = (StrUtil.isNotBlank(exportDto.getProvinceName()) ? exportDto.getProvinceName() : "")
                             + (StrUtil.isNotBlank(exportDto.getCityName()) ? exportDto.getCityName() : "")
                             + (StrUtil.isNotBlank(exportDto.getAddress1()) ? exportDto.getAddress1() : "")
                             + (StrUtil.isNotBlank(exportDto.getAddress2()) ? exportDto.getAddress2() : "");
            //去除地址中存在的逗号、引号、回车、空格
            address = replaceStr(address);
            if (address.length() <= 15) {
                catDto.setAddress1(address);
            } else if (address.length() <= 30) {
                catDto.setAddress1(address.substring(0, 15));
                catDto.setAddress2(address.substring(15));
            } else {
                catDto.setAddress1(address.substring(0, 15));
                catDto.setAddress2(address.substring(15, 30));
                catDto.setAddress3(address.substring(30));
            }
            //电话号码为空置为0
            if (StrUtil.isBlank(catDto.getPhone())) {
                catDto.setPhone("0");
            } else {
                catDto.setPhone(catDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (StrUtil.isNotBlank(catDto.getDeliveryDate())) {
                catDto.setDeliveryDate(catDto.getDeliveryDate().replaceAll("-", "/"));
                /*if (catDto.getDeliveryDate().matches(regex)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(catDto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                        catDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                }
                if (catDto.getDeliveryDate().matches(regex1)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(catDto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                        catDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                    catDto.setDeliveryDate(catDto.getDeliveryDate().replaceAll("-", "/"));
                }*/
            }
            //时间带需要变换
            if (StrUtil.isNotBlank(exportDto.getDeliveryTimeName())) {
                String timeBand;
                try {
                    int length = exportDto.getDeliveryTimeName().length();
                    if (length > 8) {
                        timeBand = exportDto.getDeliveryTimeName().substring(0, 2) + exportDto.getDeliveryTimeName().substring(6, 8);
                    } else if (exportDto.getDeliveryTimeName().contains("午前中")) {
                        timeBand = "0812";
                    } else if (exportDto.getDeliveryTimeName().contains("指定なし")) {
                        timeBand = "";
                    } else if (length == 4) {
                        timeBand = exportDto.getDeliveryTimeName();
                    } else {
                        throw new Exception();
                    }
                } catch (Exception e) {
                    timeBand = exportDto.getDeliveryTimeName().replace("-", "");
                }
                catDto.setDeliveryTimeName(timeBand);
            }

            //宅急便还是使用sku拼接的方式，投函多件分行处理
            if (exportDto.getTrackId().equals(300L) || exportDto.getTrackId().equals(500L)) {
                if (StrUtil.isNotBlank(exportDto.getPostCode())) {
                    LocationCategoryDo locationCategoryDo = postalMatchLc.get(extractDigits(exportDto.getPostCode()));
                    if (Objects.nonNull(locationCategoryDo)) {
                        catDto.setShipSectionName2(locationCategoryDo.getTypeCode());
                    }
                }
                List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(exportDto.getId());
                if (CollUtil.isEmpty(outboundProductDoList)) {
                    continue;
                }
                //合并相同SKU
                outboundProductDoList = new ArrayList<>(outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                    o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                    o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                    return o1;
                })).values());
                //コンパクト  B 列， 固定值   是  8
                if (exportDto.getTrackId().equals(500L)) {
                    catDto.setB(String.valueOf(8));
                }
                //宅急便  B 列， 固定值   是  0
                if (exportDto.getTrackId().equals(300L)) {
                    catDto.setB(String.valueOf(0));
                }
                //品目 多种品类就是杂货  商品没有品目置空
                //种类数量
                Map<Long, String> finalCategoryIdMatchName = categoryIdMatchName;
                Set<String> proTypeList = outboundProductDoList.stream()
                        .map(i -> this.checkSuitcaseOrNot(productIdMatchDo.get(i.getProductId()).getSku()) ? "スーツケース" : finalCategoryIdMatchName.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                        .filter(StrUtil::isNotBlank)
                        .collect(Collectors.toSet());
                if (proTypeList.size() > 1) {
                    catDto.setItemName("雑貨 " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
                } else {
                    String type = "未分類";
                    if (proTypeList.size() > 0) {
                        type = proTypeList.iterator().next();
                    }
                    catDto.setItemName(type + " " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
                }
                //sku优先级：简体sku -> productSku
//                catDto.setProductCode1(
//                        outboundProductDoList.stream()
//                                .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                        + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? "*" + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
//                                ).sorted().collect(Collectors.joining("・"))
//                );
                catDto.setProductCode1(
                        outboundProductDoList.stream()
                                .map(i -> (productIdMatchDo.get(i.getProductId()).getSku())
                                          + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? "*" + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
                                ).sorted().collect(Collectors.joining("・"))
                );
                if (Objects.nonNull(jpRegionDo)) {
                    int postcode = Integer.parseInt(extractDigits(exportDto.getPostCode()));
                    //沖縄県特殊处理
//                    if (jpRegionDo.getPostCodeStart() <= postcode && postcode <= jpRegionDo.getPostCodeEnd()) {
//                        if (proTypeList.contains("扇風機") || outboundProductDoList.stream()
//                                .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                ).anyMatch(this::startsWithE1ToE24)) {
//                            catDto.setItemName(catDto.getItemName() + " 【専用シール貼】");
//                        }
//                    }
                    if (jpRegionDo.getPostCodeStart() <= postcode && postcode <= jpRegionDo.getPostCodeEnd()) {
                        if (proTypeList.contains("扇風機") || outboundProductDoList.stream()
                                .map(i -> (productIdMatchDo.get(i.getProductId()).getSku())).anyMatch(this::startsWithE1ToE24)) {
                            catDto.setItemName(catDto.getItemName() + " 【専用シール貼】");
                        }
                    }
                }
                int skuStrLength = StrUtil.isBlank(catDto.getProductCode1()) ? 0 : catDto.getProductCode1().length();
                //宅急便数据sku拼接太长根据情况分割
                if (skuStrLength > 25 && skuStrLength < 50) {
                    String[] skuArr = catDto.getProductCode1().split("・");
                    skuArr = Arrays.stream(skuArr).sorted().toArray(String[]::new);
                    int splitLine = skuArr.length / 2;
                    catDto.setItemName(catDto.getItemName() + "・" + String.join("・", Arrays.copyOfRange(skuArr, 0, splitLine)));
                    catDto.setProductCode1(String.join("・", Arrays.copyOfRange(skuArr, splitLine, skuArr.length)));
                }
                catDto.setCode(outboundProductDoList.stream().anyMatch(i -> this.checkSuitcaseOrNot(productIdMatchDo.get(i.getProductId()).getSku())) ? "20" : "");
            } else {
                catDto.setB("A");
                if (StrUtil.isNotBlank(exportDto.getPostCode())) {
                    LocationCategoryDo locationCategoryDo = postalMatchLc.get(extractDigits(exportDto.getPostCode()));
                    if (Objects.nonNull(locationCategoryDo)) {
                        catDto.setShipSectionName2(locationCategoryDo.getCategory());
                    }
                }
                //投函多件
                List<OrderOutboundPackageDo> packageDoListByOrderId = outIdMatchPackages.get(exportDto.getId());
                if (CollUtil.isEmpty(packageDoListByOrderId)) {
                    continue;
                }
                boolean multi_package = packageDoListByOrderId.stream()
                                                .mapToInt(OrderOutboundPackageDo::getSerialNumber)
                                                .max().getAsInt() > 1;
                for (OrderOutboundPackageDo packageDo : packageDoListByOrderId) {
                    List<OrderOutboundPackageDetailDo> packageDetailDoList = packIdMatchSkuInfo.get(packageDo.getId());
                    if (CollUtil.isEmpty(packageDetailDoList)) {
                        continue;
                    }
                    packageDetailDoList = new ArrayList<>(
                            packageDetailDoList.stream().collect(Collectors.toMap(OrderOutboundPackageDetailDo::getProductId, i -> i, (o1, o2) -> {
                                o1.setQty(o1.getQty() + o2.getQty());
                                return o1;
                            })).values()
                    );
                    String outboundNo = multi_package
                            ? catDto.getOutboundNo() + "-" + packageDo.getSerialNumber()
                            : catDto.getOutboundNo();
//                    OrderFileByBlackCatDto dto = new OrderFileByBlackCatDto();
//                    BeanUtils.copyProperties(catDto, dto);
                    OrderFileByBlackCatDto dto = BeanConvert.INSTANCE.copyOrderFileByBlackCatDto(catDto);
                    dto.setOutboundNo(outboundNo);
                    //这个包裹品目
                    Map<Long, String> finalCategoryIdMatchName1 = categoryIdMatchName;
                    Set<String> packageProductType = packageDetailDoList.stream()
                            .map(i -> i.getSku().startsWith("h1-") ? "スーツケース" : finalCategoryIdMatchName1.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                            .filter(StrUtil::isNotBlank)
                            .collect(Collectors.toSet());
                    if (packageProductType.size() > 1) {
                        dto.setItemName("雑貨 " + packageDetailDoList.stream().map(OrderOutboundPackageDetailDo::getQty).reduce(0, Integer::sum));
                    } else {
                        String type = "未分類";
                        if (packageProductType.size() > 0) {
                            type = packageProductType.iterator().next();
                        }
                        dto.setItemName(type + " " + packageDetailDoList.stream().map(OrderOutboundPackageDetailDo::getQty).reduce(0, Integer::sum));
                    }
                    String sku = packageDetailDoList.stream().map(i -> i.getSku() + (i.getQty() > 1 ? " * " + i.getQty() : "")).sorted().collect(Collectors.joining(" ・ "));
                    dto.setProductCode1(sku);
                    //投函置空时间带
                    dto.setDeliveryTimeName("");
                    dto.setCode(packageDetailDoList.stream().anyMatch(i -> i.getSku().startsWith("h1-")) ? "20" : "");
                    addList.add(dto);
                }
            }
            finalCatDtoList.add(catDto);
        }
        List<Long> temp = addList.stream().map(OrderFileByBlackCatDto::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(temp)) {
            catDtoList = catDtoList.stream().filter(i -> !temp.contains(i.getId())).collect(Collectors.toList());
            catDtoList.addAll(addList);
        }
        return catDtoList.stream().sorted(Comparator.comparing(orderField, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    private List<OrderFileByBlackCatDto> handlerExportBeforeForBlackCatV2(List<OutboundOldExportDto> dtoList, Function<OrderFileByBlackCatDto, String> orderField) {
        if (CollUtil.isEmpty(dtoList)) {
            return Collections.emptyList();
        }
        List<Long> outIds = dtoList.stream().map(OutboundOldExportDto::getId).collect(Collectors.toList());
        //获取投函分包裹信息
        Map<Long, List<OrderOutboundPackageDo>> outIdMatchPackages = outboundPackageService.lambdaQuery()
                .in(OrderOutboundPackageDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDo::getOutboundId));
        Map<Long, List<OrderOutboundPackageDetailDo>> packIdMatchSkuInfo = outboundPackageDetailService.lambdaQuery()
                .in(OrderOutboundPackageDetailDo::getPackageId, outIdMatchPackages.values().stream().flatMap(List::stream).map(OrderOutboundPackageDo::getId).collect(Collectors.toSet()))
                .list().stream().collect(Collectors.groupingBy(OrderOutboundPackageDetailDo::getPackageId));
        Map<Long, List<OrderOutboundProductDo>> outIdMatchSkuInfo = outboundProductService.lambdaQuery()
                .in(OrderOutboundProductDo::getOutboundId, outIds)
                .list().stream().collect(Collectors.groupingBy(OrderOutboundProductDo::getOutboundId));
        Map<Long, ProductDo> productIdMatchDo = productService.lambdaQuery()
                .in(ProductDo::getId, outIdMatchSkuInfo.values().stream().flatMap(List::stream).map(OrderOutboundProductDo::getProductId).collect(Collectors.toList()))
                .list().stream().collect(Collectors.toMap(ProductDo::getId, val -> val));
        Set<Long> productCategoryIdSet = productIdMatchDo.values().stream().map(ProductDo::getCategoryId).filter(Objects::nonNull).collect(Collectors.toSet());
        Map<Long, String> categoryIdMatchName = new HashMap<>();
        if (CollUtil.isNotEmpty(productCategoryIdSet)) {
            categoryIdMatchName = productCategoryService.lambdaQuery()
                    .in(ProductCategoryDo::getId, productCategoryIdSet)
                    .list().stream().collect(Collectors.toMap(ProductCategoryDo::getId, i -> !i.getFullPathName().contains("\\") ? i.getFullPathName() : i.getFullPathName().substring(0, i.getFullPathName().indexOf("\\"))));
        }
        Map<String, LocationCategoryDo> postalMatchLc = locationCategoryDao.selectList(Wrappers.<LocationCategoryDo>lambdaQuery().in(LocationCategoryDo::getPostcode, dtoList.stream()
                .map(i -> StrUtil.isNotBlank(i.getPostCode()) ? extractDigits(i.getPostCode()) : "").collect(Collectors.toSet()))
        ).stream().collect(Collectors.toMap(LocationCategoryDo::getPostcode, val -> val, (o1, o2) -> o1));
        JpRegionDo jpRegionDo = jpRegionService.lambdaQuery().eq(JpRegionDo::getName, "沖縄県").last("limit 1").one();
        List<OrderFileByBlackCatDto> catDtoList = new ArrayList<>(5000);
        List<OrderFileByBlackCatDto> addList = new ArrayList<>(1000);
        List<OrderFileByBlackCatDto> finalCatDtoList = catDtoList;
        for (OutboundOldExportDto dto1 : dtoList) {
//            OrderFileByBlackCatDto catDto = new OrderFileByBlackCatDto();
//            BeanUtils.copyProperties(dto1, catDto);
            OrderFileByBlackCatDto catDto = BeanConvert.INSTANCE.outboundOldExportDtoToOrderFileByBlackCatDto(dto1);
            //A列管理番号 B列注文番号
            catDto.setOutboundNo(dto1.getOutboundNo());
            catDto.setB(dto1.getPlatformOrderNo());
            String address = (StrUtil.isNotBlank(dto1.getProvinceName()) ? dto1.getProvinceName() : "")
                             + (StrUtil.isNotBlank(dto1.getCityName()) ? dto1.getCityName() : "")
                             + (StrUtil.isNotBlank(dto1.getAddress1()) ? dto1.getAddress1() : "")
                             + (StrUtil.isNotBlank(dto1.getAddress2()) ? dto1.getAddress2() : "");
            //去除地址中存在的逗号、引号、回车、空格
            address = replaceStr(address);
            if (address.length() <= 15) {
                catDto.setAddress1(address);
            } else if (address.length() <= 30) {
                catDto.setAddress1(address.substring(0, 15));
                catDto.setAddress2(address.substring(15));
            } else {
                catDto.setAddress1(address.substring(0, 15));
                catDto.setAddress2(address.substring(15, 30));
                catDto.setAddress3(address.substring(30));
            }
            //电话号码为空置为0
            if (StrUtil.isBlank(catDto.getPhone())) {
                catDto.setPhone("0");
            } else {
                catDto.setPhone(catDto.getPhone().replaceAll("\\+81", "0"));
            }
            if (StrUtil.isNotBlank(catDto.getDeliveryDate())) {
                catDto.setDeliveryDate(catDto.getDeliveryDate().replaceAll("-", "/"));
                /*if (catDto.getDeliveryDate().matches(regex)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(catDto.getDeliveryDate(), "yyyy/MM/dd").isBefore(new Date())) {
                        catDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                }
                if (catDto.getDeliveryDate().matches(regex1)) {
                    //配送日在今天之前，将日期改为明天
                    if (DateUtil.parse(catDto.getDeliveryDate(), "yyyy-MM-dd").isBefore(new Date())) {
                        catDto.setDeliveryDate(DateUtil.format(LocalDateTime.now().plusDays(1), "yyyy/MM/dd"));
                    }
                    catDto.setDeliveryDate(catDto.getDeliveryDate().replaceAll("-", "/"));
                }*/
            }
            //时间带需要变换
            if (StrUtil.isNotBlank(dto1.getDeliveryTimeName())) {
                String timeBand;
                try {
                    int length = dto1.getDeliveryTimeName().length();
                    if (length > 8) {
                        timeBand = dto1.getDeliveryTimeName().substring(0, 2) + dto1.getDeliveryTimeName().substring(6, 8);
                    } else if (dto1.getDeliveryTimeName().contains("午前中")) {
                        timeBand = "0812";
                    } else if (dto1.getDeliveryTimeName().contains("指定なし")) {
                        timeBand = "";
                    } else if (length == 4) {
                        timeBand = dto1.getDeliveryTimeName();
                    } else {
                        throw new Exception();
                    }
                } catch (Exception e) {
                    timeBand = dto1.getDeliveryTimeName().replace("-", "");
                }
                catDto.setDeliveryTimeName(timeBand);
            }

            //宅急便还是使用sku拼接的方式，投函多件分行处理
            if (dto1.getTrackId().equals(300L) || dto1.getTrackId().equals(500L)) {
                if (StrUtil.isNotBlank(dto1.getPostCode())) {
                    LocationCategoryDo locationCategoryDo = postalMatchLc.get(extractDigits(dto1.getPostCode()));
                    if (Objects.nonNull(locationCategoryDo)) {
                        catDto.setShipSectionName2(locationCategoryDo.getTypeCode());
                    }
                }
                List<OrderOutboundProductDo> outboundProductDoList = outIdMatchSkuInfo.get(dto1.getId());
                if (CollUtil.isEmpty(outboundProductDoList)) {
                    continue;
                }
                //合并相同SKU
                outboundProductDoList = new ArrayList<>(outboundProductDoList.stream().collect(Collectors.toMap(OrderOutboundProductDo::getProductId, i -> i, (o1, o2) -> {
                    o1.setForecastQty(o1.getForecastQty() + o2.getForecastQty());
                    o1.setOutboundQty(o1.getOutboundQty() + o2.getOutboundQty());
                    return o1;
                })).values());
                //コンパクト  B 列， 固定值   是  8
                if (dto1.getTrackId().equals(500L)) {
                    catDto.setB(String.valueOf(8));
                }
                //宅急便  B 列， 固定值   是  0
                if (dto1.getTrackId().equals(300L)) {
                    if (StrUtil.isNotBlank(dto1.getDeliveryTimeName())) {
                        String timeBand;
                        try {
                            int length = dto1.getDeliveryTimeName().length();
                            if (length > 8) {
                                timeBand = DeliveryTimeBand.getCodeByTimeBand(dto1.getDeliveryTimeName().substring(0, 2) + dto1.getDeliveryTimeName().substring(6, 8));
                            } else if (dto1.getDeliveryTimeName().contains("午前中")) {
                                timeBand = "01";
                            } else if (dto1.getDeliveryTimeName().contains("指定なし")) {
                                timeBand = "00";
                            } else if (length == 4) {
                                timeBand = DeliveryTimeBand.getCodeByTimeBand(dto1.getDeliveryTimeName());
                            } else {
                                throw new Exception();
                            }
                        } catch (Exception e) {
                            timeBand = dto1.getDeliveryTimeName().replace("-", "");
                        }
                        catDto.setDeliveryTimeName(timeBand);
                    }
                }
                //品目 多种品类就是杂货  商品没有品目置空
                //种类数量
                Map<Long, String> finalCategoryIdMatchName = categoryIdMatchName;
                Set<String> proTypeList = outboundProductDoList.stream()
                        .map(i -> this.checkSuitcaseOrNot(productIdMatchDo.get(i.getProductId()).getSku()) ? "スーツケース" : finalCategoryIdMatchName.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                        .filter(StrUtil::isNotBlank)
                        .collect(Collectors.toSet());
                if (proTypeList.size() > 1) {
                    catDto.setItemName("雑貨 " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
                } else {
                    String type = "未分類";
                    if (proTypeList.size() > 0) {
                        type = proTypeList.iterator().next();
                    }
                    catDto.setItemName(type + " " + outboundProductDoList.stream().map(item -> item.getOutboundQty().equals(0) ? item.getForecastQty() : item.getOutboundQty()).reduce(0, Integer::sum));
                }
                //sku优先级：简体sku -> productSku  -> itemCode
//                catDto.setProductCode1(
//                        outboundProductDoList.stream()
//                                .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                        + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? "*" + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
//                                ).sorted().collect(Collectors.joining("・"))
//                );
                catDto.setProductCode1(
                        outboundProductDoList.stream()
                                .map(i -> (productIdMatchDo.get(i.getProductId()).getSku())
                                          + ((i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) > 1 ? "*" + (i.getOutboundQty().equals(0) ? i.getForecastQty() : i.getOutboundQty()) : "")
                                ).sorted().collect(Collectors.joining("・"))
                );
                if (Objects.nonNull(jpRegionDo)) {
                    int postcode = Integer.parseInt(extractDigits(dto1.getPostCode()));
                    //沖縄県特殊处理
//                    if (jpRegionDo.getPostCodeStart() <= postcode && postcode <= jpRegionDo.getPostCodeEnd()) {
//                        if (proTypeList.contains("扇風機") || outboundProductDoList.stream()
//                                .map(i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? productIdMatchDo.get(i.getProductId()).getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                ).anyMatch(this::startsWithE1ToE24)) {
//                            catDto.setItemName(catDto.getItemName() + " 【専用シール貼】");
//                        }
//                    }
                    if (jpRegionDo.getPostCodeStart() <= postcode && postcode <= jpRegionDo.getPostCodeEnd()) {
                        if (proTypeList.contains("扇風機") || outboundProductDoList.stream().map(i -> (productIdMatchDo.get(i.getProductId()).getSku())).anyMatch(this::startsWithE1ToE24)) {
                            catDto.setItemName(catDto.getItemName() + " 【専用シール貼】");
                        }
                    }
                }
                catDto.setCode(outboundProductDoList.stream().anyMatch(i -> this.checkSuitcaseOrNot(productIdMatchDo.get(i.getProductId()).getSku())) ? "20" : "5");
            } else {
                //投函多件
                List<OrderOutboundPackageDo> packageDoListByOrderId = outIdMatchPackages.get(dto1.getId());
                if (CollUtil.isEmpty(packageDoListByOrderId)) {
                    continue;
                }
                boolean multi_package = packageDoListByOrderId.stream()
                                                .mapToInt(OrderOutboundPackageDo::getSerialNumber)
                                                .max().getAsInt() > 1;
                for (OrderOutboundPackageDo packageDo : packageDoListByOrderId) {
                    List<OrderOutboundPackageDetailDo> packageDetailDoList = packIdMatchSkuInfo.get(packageDo.getId());
                    if (CollUtil.isEmpty(packageDetailDoList)) {
                        continue;
                    }
                    packageDetailDoList = new ArrayList<>(
                            packageDetailDoList.stream().collect(Collectors.toMap(OrderOutboundPackageDetailDo::getProductId, i -> i, (o1, o2) -> {
                                o1.setQty(o1.getQty() + o2.getQty());
                                return o1;
                            })).values()
                    );
                    String outboundNo = multi_package
                            ? catDto.getOutboundNo() + "-" + packageDo.getSerialNumber()
                            : catDto.getOutboundNo();
//                    OrderFileByBlackCatDto dto = new OrderFileByBlackCatDto();
//                    BeanUtils.copyProperties(catDto, dto);
                    OrderFileByBlackCatDto dto = BeanConvert.INSTANCE.copyOrderFileByBlackCatDto(catDto);
                    dto.setOutboundNo(outboundNo);
                    //这个包裹品目
                    Map<Long, String> finalCategoryIdMatchName1 = categoryIdMatchName;
                    Set<String> packageProductType = packageDetailDoList.stream()
                            .map(i -> i.getSku().startsWith("h1-") || i.getSku().startsWith("h2-") ? "スーツケース" : finalCategoryIdMatchName1.get(productIdMatchDo.get(i.getProductId()).getCategoryId()))
                            .filter(StrUtil::isNotBlank)
                            .collect(Collectors.toSet());
                    if (packageProductType.size() > 1) {
                        dto.setItemName("雑貨 " + packageDetailDoList.stream().map(OrderOutboundPackageDetailDo::getQty).reduce(0, Integer::sum));
                    } else {
                        String type = "未分類";
                        if (packageProductType.size() > 0) {
                            type = packageProductType.iterator().next();
                        }
                        dto.setItemName(type + " " + packageDetailDoList.stream().map(OrderOutboundPackageDetailDo::getQty).reduce(0, Integer::sum));
                    }
//                    String sku = packageDetailDoList.stream().map(
//                            i -> (StrUtil.isBlank(productIdMatchDo.get(i.getProductId()).getProductAliasName()) ? i.getSku() : productIdMatchDo.get(i.getProductId()).getProductAliasName())
//                                    + (i.getQty() > 1 ? " * " + i.getQty() : "")
//                    ).sorted().collect(Collectors.joining(" ・ "));
                    String sku = packageDetailDoList.stream().map(i -> (i.getSku()) + (i.getQty() > 1 ? " * " + i.getQty() : "")).sorted().collect(Collectors.joining(" ・ "));
                    dto.setProductCode1(sku);
                    //投函置空时间带
                    dto.setDeliveryTimeName("");
                    dto.setCode(packageDetailDoList.stream().anyMatch(i -> i.getSku().startsWith("h1-") || i.getSku().startsWith("h2-")) ? "20" : "2");
                    addList.add(dto);
                }
            }
            finalCatDtoList.add(catDto);
        }
        List<Long> temp = addList.stream().map(OrderFileByBlackCatDto::getId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(temp)) {
            catDtoList = catDtoList.stream().filter(i -> !temp.contains(i.getId())).collect(Collectors.toList());
            catDtoList.addAll(addList);
        }
        return catDtoList.stream().sorted(Comparator.comparing(orderField, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
    }

    /**
     * 去除逗号、回车、引号字符
     */
    private static String replaceStr(String str) {
        if ((str == null) || (str.length() == 0)) {
            return str;
        }
        return str.replaceAll("[,\\n\" ]", "");
    }

    /**
     * 本地仓 文件      宅急便  O列 加 文字   【専用シール貼】
     * 前提是，地址是 沖縄 地址，商品 (品名：扇風機 或者 sku e1到 e24开头 )
     */
    private boolean startsWithE1ToE24(String input) {
        if (input == null) {
            return false;
        }
        Pattern pattern = Pattern.compile("^e(1[0-9]|2[0-4]|[1-9])(?!\\d)");
        Matcher matcher = pattern.matcher(input);
        return matcher.lookingAt();
    }

    private final static List<String> suitcaseList = Arrays.asList(
            "h1-l55812",
            "h1-l55829",
            "h1-l55836",
            "h1-l55843",
            "h1-l56611",
            "h1-l56628",
            "h1-m55768",
            "h1-m55775",
            "h1-m55782",
            "h1-m55799",
            "h1-m56574",
            "h1-m56581",
            "h1-s55713",
            "h1-s55720",
            "h1-s55737",
            "h1-s55744",
            "h1-s56598",
            "h1-s56604",
            "h2-m58196",
            "h2-m58233",
            "h2-m58257",
            "h2-m58271",
            "h2-m58462",
            "h2-s58189",
            "h2-s58202",
            "h2-s58219",
            "h2-s58226",
            "h2-s58240",
            "h2-s58264",
            "h3-58295",
            "h3-58301",
            "h3-58318",
            "h3-58325",
            "h3-58332",
            "h3-58349",
            "h3-58356",
            "h3-58363",
            "h4-58370",
            "h4-58387",
            "h4-58394",
            "h4-58400"
    );

    /**
     * 判断sku是否为旅行箱
     */
    private boolean checkSuitcaseOrNot(String sku) {
        if (StrUtil.isBlank(sku)) {
            return false;
        }
        return suitcaseList.contains(sku);
    }

    /**
     * 用于stream流的filter方法做实体类的某个属性去重
     */
    static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        //putIfAbsent方法添加键值对，如果map集合中没有该key对应的值，则直接添加，并返回null，如果已经存在对应的值，则依旧为原来的值。
        //如果返回null表示添加数据成功(不重复)，不重复(null==null :TRUE)
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    public static String extractDigits(String input) {
        // 正则表达式解释:
        // [０-９]   匹配全角数字(Unicode范围: U+FF10到U+FF19)
        // [0-9]    匹配半角数字
        Pattern pattern = Pattern.compile("[０-９]|[0-9]");
        Matcher matcher = pattern.matcher(input);
        StringBuilder result = new StringBuilder();

        while (matcher.find()) {
            String digit = matcher.group();
            // 全角数字转半角: '０'的Unicode是FF10(65296)，'0'是30(48)
            if (digit.charAt(0) >= '０') { // 判断是否为全角字符
                char halfwidthDigit = (char) (digit.charAt(0) - 65296 + 48);
                result.append(halfwidthDigit);
            } else {
                result.append(digit);
            }
        }

        return result.toString();
    }

    public static void main(String[] args) {
        String s = "０0１１-l55812";
        //替换非数字的
        System.out.println(extractDigits(s));
    }
}
